mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
Merge branch 'media-view-options' of https://github.com/nextmcloud/android into media-view-options
This commit is contained in:
commit
e842fa134a
75 changed files with 1214 additions and 292 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
|||
## 3.20.0 (May 3rd, 2022)
|
||||
|
||||
- Built-in PDF viewer
|
||||
- Built-in document scanner
|
||||
- Better choices for storage permissions
|
||||
- File locking support
|
||||
- Better UI for media gallery
|
||||
- Many bugfixes and improvements
|
||||
|
||||
Minimum: NC 16 Server, Android 6.0 Marshmallow
|
||||
|
||||
For a full list, please see https://github.com/nextcloud/android/milestone/64
|
||||
## 3.19.1 (March 10, 2022)
|
||||
|
||||
- Minor fixes and improvements
|
||||
|
|
|
@ -54,15 +54,6 @@ configurations.configureEach {
|
|||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
maven { url "https://jitpack.io" }
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://plugins.gradle.org/m2/'
|
||||
}
|
||||
}
|
||||
|
||||
// semantic versioning for version code
|
||||
def versionMajor = 3
|
||||
def versionMinor = 20
|
||||
|
@ -250,7 +241,7 @@ dependencies {
|
|||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.24'
|
||||
implementation 'com.github.tobiaskaminsky:qrcodescanner:0.1.2.4' // 'com.github.blikoon:QRCodeScanner:0.1.2'
|
||||
implementation 'com.google.android:flexbox:2.0.1'
|
||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||
implementation('com.github.bumptech.glide:glide:3.8.0') {
|
||||
exclude group: "com.android.support"
|
||||
}
|
||||
|
@ -284,7 +275,7 @@ dependencies {
|
|||
implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.1'
|
||||
|
||||
// Shimmer animation
|
||||
implementation 'com.elyeproj.libraries:loaderviewlibrary:2.0.0'
|
||||
implementation 'io.github.elye:loaderviewlibrary:3.0.0'
|
||||
|
||||
// dependencies for markdown rendering
|
||||
implementation "io.noties.markwon:core:$markwonVersion"
|
||||
|
@ -327,6 +318,7 @@ dependencies {
|
|||
// Android JUnit Runner
|
||||
androidTestImplementation "androidx.test:runner:$androidxTestVersion"
|
||||
androidTestUtil "androidx.test:orchestrator:$androidxTestVersion"
|
||||
androidTestImplementation "androidx.test:core-ktx:$androidxTestVersion"
|
||||
|
||||
// Espresso
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
|
||||
|
|
|
@ -202,7 +202,9 @@ naming:
|
|||
functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
|
||||
excludeClassPattern: '$^'
|
||||
ignoreOverridden: true
|
||||
excludes: "**/*Test.kt"
|
||||
excludes:
|
||||
- "**/*Test.kt"
|
||||
- "**/*IT.kt"
|
||||
FunctionParameterNaming:
|
||||
active: true
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
|
@ -324,7 +326,9 @@ style:
|
|||
ignoreAnnotation: false
|
||||
ignoreNamedArgument: true
|
||||
ignoreEnums: false
|
||||
excludes: "**/*Test.kt"
|
||||
excludes:
|
||||
- "**/*Test.kt"
|
||||
- "**/*IT.kt"
|
||||
MandatoryBracesIfStatements:
|
||||
active: false
|
||||
MaxLineLength:
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.mockito.kotlin.eq
|
|||
import org.mockito.kotlin.verify
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ContentResolverHelperTest {
|
||||
class ContentResolverHelperIT {
|
||||
|
||||
companion object {
|
||||
private val URI = Uri.parse("http://foo.bar")
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.files
|
||||
|
||||
import android.view.Menu
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.test.core.app.launchActivity
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.nextcloud.client.TestActivity
|
||||
import com.nextcloud.client.account.User
|
||||
import com.owncloud.android.AbstractIT
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.files.services.FileDownloader
|
||||
import com.owncloud.android.files.services.FileUploader
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType
|
||||
import com.owncloud.android.lib.resources.status.CapabilityBooleanType
|
||||
import com.owncloud.android.lib.resources.status.OCCapability
|
||||
import com.owncloud.android.services.OperationsService
|
||||
import com.owncloud.android.ui.activity.ComponentsGetter
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FileMenuFilterIT : AbstractIT() {
|
||||
|
||||
@MockK
|
||||
private lateinit var mockComponentsGetter: ComponentsGetter
|
||||
|
||||
@MockK
|
||||
private lateinit var mockStorageManager: FileDataStorageManager
|
||||
|
||||
@MockK
|
||||
private lateinit var mockFileUploaderBinder: FileUploader.FileUploaderBinder
|
||||
|
||||
@MockK
|
||||
private lateinit var mockFileDownloaderBinder: FileDownloader.FileDownloaderBinder
|
||||
|
||||
@MockK
|
||||
private lateinit var mockOperationsServiceBinder: OperationsService.OperationsServiceBinder
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
every { mockFileUploaderBinder.isUploading(any(), any()) } returns false
|
||||
every { mockComponentsGetter.fileUploaderBinder } returns mockFileUploaderBinder
|
||||
every { mockFileDownloaderBinder.isDownloading(any(), any()) } returns false
|
||||
every { mockComponentsGetter.fileDownloaderBinder } returns mockFileDownloaderBinder
|
||||
every { mockOperationsServiceBinder.isSynchronizing(any(), any()) } returns false
|
||||
every { mockComponentsGetter.operationsServiceBinder } returns mockOperationsServiceBinder
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter_noLockingCapability_lockItemsInvisible() {
|
||||
val capability = OCCapability().apply {
|
||||
endToEndEncryption = CapabilityBooleanType.UNKNOWN
|
||||
}
|
||||
|
||||
val file = OCFile("/foo.md")
|
||||
|
||||
testLockingVisibilities(
|
||||
capability,
|
||||
file,
|
||||
ExpectedLockVisibilities(lockFile = false, unlockFile = false, lockedBy = false, lockedUntil = false)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter_lockingCapability_fileUnlocked_lockVisible() {
|
||||
val capability = OCCapability().apply {
|
||||
endToEndEncryption = CapabilityBooleanType.UNKNOWN
|
||||
filesLockingVersion = "1.0"
|
||||
}
|
||||
|
||||
val file = OCFile("/foo.md")
|
||||
|
||||
testLockingVisibilities(
|
||||
capability,
|
||||
file,
|
||||
ExpectedLockVisibilities(lockFile = true, unlockFile = false, lockedBy = false, lockedUntil = false)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter_lockingCapability_fileLocked_lockedByAndProps() {
|
||||
val capability = OCCapability().apply {
|
||||
endToEndEncryption = CapabilityBooleanType.UNKNOWN
|
||||
filesLockingVersion = "1.0"
|
||||
}
|
||||
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = true
|
||||
lockType = FileLockType.MANUAL
|
||||
lockOwnerId = user.accountName.split("@")[0]
|
||||
lockOwnerDisplayName = "TEST"
|
||||
lockTimestamp = 1000 // irrelevant
|
||||
lockTimeout = 1000 // irrelevant
|
||||
}
|
||||
|
||||
testLockingVisibilities(
|
||||
capability,
|
||||
file,
|
||||
ExpectedLockVisibilities(lockFile = false, unlockFile = true, lockedBy = true, lockedUntil = true)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter_lockingCapability_fileLockedByOthers_lockedByAndProps() {
|
||||
val capability = OCCapability().apply {
|
||||
endToEndEncryption = CapabilityBooleanType.UNKNOWN
|
||||
filesLockingVersion = "1.0"
|
||||
}
|
||||
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = true
|
||||
lockType = FileLockType.MANUAL
|
||||
lockOwnerId = "A_DIFFERENT_USER"
|
||||
lockOwnerDisplayName = "A_DIFFERENT_USER"
|
||||
lockTimestamp = 1000 // irrelevant
|
||||
lockTimeout = 1000 // irrelevant
|
||||
}
|
||||
testLockingVisibilities(
|
||||
capability,
|
||||
file,
|
||||
ExpectedLockVisibilities(lockFile = false, unlockFile = false, lockedBy = true, lockedUntil = true)
|
||||
)
|
||||
}
|
||||
|
||||
private data class ExpectedLockVisibilities(
|
||||
val lockFile: Boolean,
|
||||
val unlockFile: Boolean,
|
||||
val lockedBy: Boolean,
|
||||
val lockedUntil: Boolean
|
||||
)
|
||||
|
||||
private fun configureCapability(capability: OCCapability) {
|
||||
every { mockStorageManager.getCapability(any<User>()) } returns capability
|
||||
every { mockStorageManager.getCapability(any<String>()) } returns capability
|
||||
every { mockComponentsGetter.storageManager } returns mockStorageManager
|
||||
}
|
||||
|
||||
private fun getMenu(activity: TestActivity): Menu {
|
||||
val inflater = activity.menuInflater
|
||||
val menu = MenuBuilder(activity)
|
||||
inflater.inflate(R.menu.item_file, menu)
|
||||
return menu
|
||||
}
|
||||
|
||||
private fun testLockingVisibilities(
|
||||
capability: OCCapability,
|
||||
file: OCFile,
|
||||
expectedLockVisibilities: ExpectedLockVisibilities
|
||||
) {
|
||||
configureCapability(capability)
|
||||
|
||||
launchActivity<TestActivity>().use {
|
||||
it.onActivity { activity ->
|
||||
val menu = getMenu(activity)
|
||||
|
||||
val sut = FileMenuFilter(file, mockComponentsGetter, activity, true, user)
|
||||
|
||||
sut.filter(menu, false)
|
||||
|
||||
Assert.assertEquals(
|
||||
expectedLockVisibilities.lockFile,
|
||||
menu.findItem(R.id.action_lock_file).isVisible
|
||||
)
|
||||
Assert.assertEquals(
|
||||
expectedLockVisibilities.unlockFile,
|
||||
menu.findItem(R.id.action_unlock_file).isVisible
|
||||
)
|
||||
Assert.assertEquals(
|
||||
expectedLockVisibilities.lockedBy,
|
||||
menu.findItem(R.id.action_locked_by).isVisible
|
||||
)
|
||||
Assert.assertEquals(
|
||||
expectedLockVisibilities.lockedUntil,
|
||||
menu.findItem(R.id.action_locked_until).isVisible
|
||||
)
|
||||
|
||||
// locked by and until should always be disabled, they're not real actions
|
||||
Assert.assertFalse(menu.findItem(R.id.action_locked_by).isEnabled)
|
||||
Assert.assertFalse(menu.findItem(R.id.action_locked_until).isEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.android.files
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType
|
||||
|
||||
object FileLockingHelper {
|
||||
/**
|
||||
* Checks whether the given `userId` can unlock the [OCFile].
|
||||
*/
|
||||
@JvmStatic
|
||||
fun canUserUnlockFile(userId: String, file: OCFile): Boolean {
|
||||
if (!file.isLocked || file.lockOwnerId == null || file.lockType != FileLockType.MANUAL) {
|
||||
return false
|
||||
}
|
||||
return file.lockOwnerId == userId
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.android.files
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.os.Build
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import com.nextcloud.utils.TimeConstants
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType
|
||||
import com.owncloud.android.utils.DisplayUtils
|
||||
|
||||
/**
|
||||
* Customizes a Menu to show locking information
|
||||
*/
|
||||
class FileLockingMenuCustomization(val context: Context) {
|
||||
fun customizeMenu(menu: Menu, file: OCFile) {
|
||||
if (file.isLocked) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
menu.setGroupDividerEnabled(true)
|
||||
}
|
||||
menu.findItem(R.id.action_locked_by).title = getLockedByText(file)
|
||||
showLockedUntil(menu, file)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLockedByText(file: OCFile): CharSequence {
|
||||
val username = file.lockOwnerDisplayName ?: file.lockOwnerId
|
||||
val resource = when (file.lockType) {
|
||||
FileLockType.COLLABORATIVE -> R.string.locked_by_app
|
||||
else -> R.string.locked_by
|
||||
}
|
||||
return DisplayUtils.createTextWithSpan(
|
||||
context.getString(resource, username),
|
||||
username,
|
||||
StyleSpan(Typeface.BOLD)
|
||||
)
|
||||
}
|
||||
|
||||
private fun showLockedUntil(menu: Menu, file: OCFile) {
|
||||
val lockedUntil: MenuItem = menu.findItem(R.id.action_locked_until)
|
||||
if (file.lockTimestamp == 0L || file.lockTimeout == 0L) {
|
||||
lockedUntil.isVisible = false
|
||||
} else {
|
||||
lockedUntil.title =
|
||||
context.getString(R.string.lock_expiration_info, getExpirationRelativeText(file))
|
||||
lockedUntil.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun getExpirationRelativeText(file: OCFile): CharSequence? {
|
||||
val expirationTimestamp = (file.lockTimestamp + file.lockTimeout) * TimeConstants.MILLIS_PER_SECOND
|
||||
return DisplayUtils.getRelativeTimestamp(context, expirationTimestamp, true)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.android.files
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ContextThemeWrapper
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import com.owncloud.android.R
|
||||
|
||||
/**
|
||||
* This is a [PopupMenu] with grayed out disabled elements
|
||||
*/
|
||||
class ThemedPopupMenu(
|
||||
context: Context,
|
||||
anchor: View
|
||||
) : PopupMenu(wrapContext(context), anchor) {
|
||||
|
||||
companion object {
|
||||
private fun wrapContext(context: Context): Context =
|
||||
ContextThemeWrapper(context, R.style.Nextcloud_Widget_PopupMenu)
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ import com.nextcloud.client.network.NetworkModule;
|
|||
import com.nextcloud.client.onboarding.OnboardingModule;
|
||||
import com.nextcloud.client.preferences.PreferencesModule;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.media.MediaControlView;
|
||||
import com.owncloud.android.ui.ThemeableSwitchPreference;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -55,6 +57,10 @@ public interface AppComponent {
|
|||
|
||||
void inject(MainApp app);
|
||||
|
||||
void inject(MediaControlView mediaControlView);
|
||||
|
||||
void inject(ThemeableSwitchPreference switchPreference);
|
||||
|
||||
@Component.Builder
|
||||
interface Builder {
|
||||
@BindsInstance
|
||||
|
|
26
app/src/main/java/com/nextcloud/utils/TimeConstants.kt
Normal file
26
app/src/main/java/com/nextcloud/utils/TimeConstants.kt
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.utils
|
||||
|
||||
object TimeConstants {
|
||||
const val MILLIS_PER_SECOND = 1000
|
||||
}
|
|
@ -45,6 +45,7 @@ import com.nextcloud.client.appinfo.AppInfo;
|
|||
import com.nextcloud.client.core.Clock;
|
||||
import com.nextcloud.client.device.PowerManagementService;
|
||||
import com.nextcloud.client.di.ActivityInjector;
|
||||
import com.nextcloud.client.di.AppComponent;
|
||||
import com.nextcloud.client.di.DaggerAppComponent;
|
||||
import com.nextcloud.client.errorhandling.ExceptionHandler;
|
||||
import com.nextcloud.client.jobs.BackgroundJobManager;
|
||||
|
@ -178,6 +179,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
@SuppressWarnings("unused")
|
||||
private boolean mBound;
|
||||
|
||||
private static AppComponent appComponent;
|
||||
|
||||
/**
|
||||
* Temporary hack
|
||||
*/
|
||||
|
@ -226,10 +229,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
super.attachBaseContext(base);
|
||||
|
||||
initGlobalContext(this);
|
||||
DaggerAppComponent.builder()
|
||||
.application(this)
|
||||
.build()
|
||||
.inject(this);
|
||||
initDagger();
|
||||
|
||||
// we don't want to handle crashes occurring inside crash reporter activity/process;
|
||||
// let the platform deal with those
|
||||
|
@ -243,6 +243,29 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
}
|
||||
}
|
||||
|
||||
private void initDagger() {
|
||||
appComponent = DaggerAppComponent.builder()
|
||||
.application(this)
|
||||
.build();
|
||||
|
||||
appComponent.inject(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>USE SPARINGLY!</b> This should only be used for injection of Theme classes in custom Views, and they need to
|
||||
* be added as methods in the {@link AppComponent} itself.
|
||||
* <p>
|
||||
* Once we adopt Hilt this won't be necessary either, as View is a supported target in Hilt.
|
||||
*
|
||||
* @return the {@link AppComponent} for this app
|
||||
*/
|
||||
public static AppComponent getAppComponent() {
|
||||
if (appComponent == null) {
|
||||
throw new IllegalStateException("Dagger not initialized!");
|
||||
}
|
||||
return appComponent;
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("ST")
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
|
@ -45,6 +45,7 @@ import com.owncloud.android.lib.common.network.WebdavEntry;
|
|||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation;
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType;
|
||||
import com.owncloud.android.lib.resources.files.model.RemoteFile;
|
||||
import com.owncloud.android.lib.resources.shares.OCShare;
|
||||
import com.owncloud.android.lib.resources.shares.ShareType;
|
||||
|
@ -70,6 +71,7 @@ import java.util.Set;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
|
||||
public class FileDataStorageManager {
|
||||
|
@ -83,9 +85,9 @@ public class FileDataStorageManager {
|
|||
public static final int ROOT_PARENT_ID = 0;
|
||||
public static final String NULL_STRING = "null";
|
||||
|
||||
private ContentResolver contentResolver;
|
||||
private ContentProviderClient contentProviderClient;
|
||||
private User user;
|
||||
private final ContentResolver contentResolver;
|
||||
private final ContentProviderClient contentProviderClient;
|
||||
private final User user;
|
||||
|
||||
public FileDataStorageManager(User user, ContentResolver contentResolver) {
|
||||
this.contentProviderClient = null;
|
||||
|
@ -208,44 +210,10 @@ public class FileDataStorageManager {
|
|||
|
||||
public boolean saveFile(OCFile ocFile) {
|
||||
boolean overridden = false;
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED, ocFile.getModificationTimestamp());
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
|
||||
ocFile.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
cv.put(ProviderTableMeta.FILE_CREATION, ocFile.getCreationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, ocFile.getFileLength());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, ocFile.getMimeType());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, ocFile.getFileName());
|
||||
cv.put(ProviderTableMeta.FILE_ENCRYPTED_NAME, ocFile.getEncryptedFileName());
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, ocFile.getParentId());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, ocFile.getRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_PATH_DECRYPTED, ocFile.getDecryptedRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_IS_ENCRYPTED, ocFile.isEncrypted());
|
||||
if (!ocFile.isFolder()) {
|
||||
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, ocFile.getStoragePath());
|
||||
final ContentValues cv = createContentValuesForFile(ocFile);
|
||||
if (ocFile.isFolder()) {
|
||||
cv.remove(ProviderTableMeta.FILE_STORAGE_PATH);
|
||||
}
|
||||
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, user.getAccountName());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, ocFile.getLastSyncDateForProperties());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, ocFile.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, ocFile.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, ocFile.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, ocFile.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, ocFile.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, ocFile.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, ocFile.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, ocFile.isUpdateThumbnailNeeded());
|
||||
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, ocFile.isDownloading());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, ocFile.getEtagInConflict());
|
||||
cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, ocFile.getUnreadCommentsCount());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_ID, ocFile.getOwnerId());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, ocFile.getOwnerDisplayName());
|
||||
cv.put(ProviderTableMeta.FILE_NOTE, ocFile.getNote());
|
||||
cv.put(ProviderTableMeta.FILE_SHAREES, new Gson().toJson(ocFile.getSharees()));
|
||||
cv.put(ProviderTableMeta.FILE_RICH_WORKSPACE, ocFile.getRichWorkspace());
|
||||
cv.put(ProviderTableMeta.FILE_HAS_PREVIEW, ocFile.isPreviewAvailable() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, ocFile.isFavorite());
|
||||
|
||||
boolean sameRemotePath = fileExists(ocFile.getRemotePath());
|
||||
if (sameRemotePath ||
|
||||
|
@ -369,7 +337,8 @@ public class FileDataStorageManager {
|
|||
|
||||
// prepare operations to insert or update files to save in the given folder
|
||||
for (OCFile ocFile : updatedFiles) {
|
||||
ContentValues contentValues = createContentValueForFile(ocFile, folder);
|
||||
ContentValues contentValues = createContentValuesForFile(ocFile);
|
||||
contentValues.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
|
||||
|
||||
if (fileExists(ocFile.getFileId()) || fileExists(ocFile.getRemotePath())) {
|
||||
long fileId;
|
||||
|
@ -423,7 +392,7 @@ public class FileDataStorageManager {
|
|||
}
|
||||
|
||||
// update metadata of folder
|
||||
ContentValues contentValues = createContentValueForFile(folder);
|
||||
ContentValues contentValues = createContentValuesForFolder(folder);
|
||||
|
||||
operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI)
|
||||
.withValues(contentValues)
|
||||
|
@ -467,76 +436,76 @@ public class FileDataStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
private ContentValues createContentValueForFile(OCFile folder) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
|
||||
folder.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimeType());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_PATH_DECRYPTED, folder.getDecryptedRemotePath());
|
||||
/**
|
||||
* Returns a {@link ContentValues} filled with values that are common to both files and folders
|
||||
* @see #createContentValuesForFile(OCFile)
|
||||
* @see #createContentValuesForFolder(OCFile)
|
||||
*/
|
||||
private ContentValues createContentValuesBase(OCFile fileOrFolder) {
|
||||
final ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED, fileOrFolder.getModificationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, fileOrFolder.getModificationTimestampAtLastSyncForData());
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, fileOrFolder.getParentId());
|
||||
cv.put(ProviderTableMeta.FILE_CREATION, fileOrFolder.getCreationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, fileOrFolder.getMimeType());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, fileOrFolder.getFileName());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, fileOrFolder.getRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_PATH_DECRYPTED, fileOrFolder.getDecryptedRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, user.getAccountName());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, folder.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, folder.isFavorite());
|
||||
cv.put(ProviderTableMeta.FILE_IS_ENCRYPTED, folder.isEncrypted());
|
||||
cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, folder.getUnreadCommentsCount());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_ID, folder.getOwnerId());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, folder.getOwnerDisplayName());
|
||||
cv.put(ProviderTableMeta.FILE_NOTE, folder.getNote());
|
||||
cv.put(ProviderTableMeta.FILE_SHAREES, new Gson().toJson(folder.getSharees()));
|
||||
cv.put(ProviderTableMeta.FILE_RICH_WORKSPACE, folder.getRichWorkspace());
|
||||
|
||||
cv.put(ProviderTableMeta.FILE_IS_ENCRYPTED, fileOrFolder.isEncrypted());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, fileOrFolder.getLastSyncDateForProperties());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, fileOrFolder.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, fileOrFolder.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, fileOrFolder.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, fileOrFolder.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, fileOrFolder.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, fileOrFolder.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, fileOrFolder.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, fileOrFolder.isFavorite());
|
||||
cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, fileOrFolder.getUnreadCommentsCount());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_ID, fileOrFolder.getOwnerId());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, fileOrFolder.getOwnerDisplayName());
|
||||
cv.put(ProviderTableMeta.FILE_NOTE, fileOrFolder.getNote());
|
||||
cv.put(ProviderTableMeta.FILE_SHAREES, new Gson().toJson(fileOrFolder.getSharees()));
|
||||
cv.put(ProviderTableMeta.FILE_RICH_WORKSPACE, fileOrFolder.getRichWorkspace());
|
||||
return cv;
|
||||
}
|
||||
|
||||
private ContentValues createContentValueForFile(OCFile file, OCFile folder) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
|
||||
cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
|
||||
/**
|
||||
* Returns a {@link ContentValues} filled with values for a folder
|
||||
* @see #createContentValuesForFile(OCFile)
|
||||
* @see #createContentValuesBase(OCFile)
|
||||
*/
|
||||
private ContentValues createContentValuesForFolder(OCFile folder) {
|
||||
final ContentValues cv = createContentValuesBase(folder);
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);
|
||||
return cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ContentValues} filled with values for a file
|
||||
* @see #createContentValuesForFolder(OCFile)
|
||||
* @see #createContentValuesBase(OCFile)
|
||||
*/
|
||||
@SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
|
||||
private ContentValues createContentValuesForFile(OCFile file) {
|
||||
final ContentValues cv = createContentValuesBase(file);
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimeType());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
|
||||
cv.put(ProviderTableMeta.FILE_ENCRYPTED_NAME, file.getEncryptedFileName());
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_PATH_DECRYPTED, file.getDecryptedRemotePath());
|
||||
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
|
||||
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, user.getAccountName());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.isUpdateThumbnailNeeded());
|
||||
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());
|
||||
cv.put(ProviderTableMeta.FILE_IS_ENCRYPTED, file.isEncrypted());
|
||||
cv.put(ProviderTableMeta.FILE_MOUNT_TYPE, file.getMountType().ordinal());
|
||||
cv.put(ProviderTableMeta.FILE_HAS_PREVIEW, file.isPreviewAvailable() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, file.getUnreadCommentsCount());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_ID, file.getOwnerId());
|
||||
cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, file.getOwnerDisplayName());
|
||||
cv.put(ProviderTableMeta.FILE_NOTE, file.getNote());
|
||||
cv.put(ProviderTableMeta.FILE_SHAREES, new Gson().toJson(file.getSharees()));
|
||||
cv.put(ProviderTableMeta.FILE_RICH_WORKSPACE, file.getRichWorkspace());
|
||||
cv.put(ProviderTableMeta.FILE_LOCKED, file.isLocked());
|
||||
final FileLockType lockType = file.getLockType();
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_TYPE, lockType != null ? lockType.getValue() : -1);
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_OWNER, file.getLockOwnerId());
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME, file.getLockOwnerDisplayName());
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_OWNER_EDITOR, file.getLockOwnerEditor());
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_TIMESTAMP, file.getLockTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_TIMEOUT, file.getLockTimeout());
|
||||
cv.put(ProviderTableMeta.FILE_LOCK_TOKEN, file.getLockToken());
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
@ -1030,6 +999,16 @@ public class FileDataStorageManager {
|
|||
ocFile.setOwnerDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME)));
|
||||
ocFile.setNote(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_NOTE)));
|
||||
ocFile.setRichWorkspace(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_RICH_WORKSPACE)));
|
||||
ocFile.setLocked(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCKED)) == 1);
|
||||
final int lockTypeInt = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TYPE));
|
||||
ocFile.setLockType(lockTypeInt != -1 ? FileLockType.fromValue(lockTypeInt) : null);
|
||||
ocFile.setLockOwnerId(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER)));
|
||||
ocFile.setLockOwnerDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME)));
|
||||
ocFile.setLockOwnerEditor(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER_EDITOR)));
|
||||
ocFile.setLockTimestamp(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TIMESTAMP)));
|
||||
ocFile.setLockTimeout(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TIMEOUT)));
|
||||
ocFile.setLockToken(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TOKEN)));
|
||||
|
||||
|
||||
String sharees = cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_SHAREES));
|
||||
|
||||
|
@ -1424,86 +1403,6 @@ public class FileDataStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void updateSharedFiles(Collection<OCFile> sharedFiles) {
|
||||
resetShareFlagsInAllFiles();
|
||||
|
||||
if (sharedFiles != null) {
|
||||
ArrayList<ContentProviderOperation> operations = new ArrayList<>(sharedFiles.size());
|
||||
|
||||
// prepare operations to insert or update files to save in the given folder
|
||||
for (OCFile file : sharedFiles) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
|
||||
file.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimeType());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
|
||||
if (!file.isFolder()) {
|
||||
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
|
||||
}
|
||||
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, user.getAccountName());
|
||||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
|
||||
file.getLastSyncDateForData()
|
||||
);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());
|
||||
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.isUpdateThumbnailNeeded() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
|
||||
|
||||
boolean existsByPath = fileExists(file.getRemotePath());
|
||||
if (existsByPath || fileExists(file.getFileId())) {
|
||||
// updating an existing file
|
||||
operations.add(
|
||||
ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
|
||||
withValues(cv).
|
||||
withSelection(ProviderTableMeta._ID + "=?",
|
||||
new String[]{String.valueOf(file.getFileId())})
|
||||
.build());
|
||||
|
||||
} else {
|
||||
// adding a new file
|
||||
operations.add(
|
||||
ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).
|
||||
withValues(cv).
|
||||
build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// apply operations in batch
|
||||
if (operations.size() > 0) {
|
||||
@SuppressWarnings("unused")
|
||||
ContentProviderResult[] results = null;
|
||||
Log_OC.d(TAG, String.format(Locale.ENGLISH, SENDING_TO_FILECONTENTPROVIDER_MSG, operations.size()));
|
||||
try {
|
||||
if (getContentResolver() != null) {
|
||||
results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
|
||||
} else {
|
||||
results = getContentProviderClient().applyBatch(operations);
|
||||
}
|
||||
|
||||
} catch (OperationApplicationException | RemoteException e) {
|
||||
Log_OC.e(TAG, EXCEPTION_MSG + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeShare(OCShare share) {
|
||||
Uri contentUriShare = ProviderTableMeta.CONTENT_URI_SHARE;
|
||||
String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND +
|
||||
|
@ -2075,6 +1974,8 @@ public class FileDataStorageManager {
|
|||
contentValues.put(ProviderTableMeta.CAPABILITIES_USER_STATUS, capability.getUserStatus().getValue());
|
||||
contentValues.put(ProviderTableMeta.CAPABILITIES_USER_STATUS_SUPPORTS_EMOJI,
|
||||
capability.getUserStatusSupportsEmoji().getValue());
|
||||
contentValues.put(ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION,
|
||||
capability.getFilesLockingVersion());
|
||||
|
||||
return contentValues;
|
||||
}
|
||||
|
@ -2224,6 +2125,8 @@ public class FileDataStorageManager {
|
|||
capability.setUserStatus(getBoolean(cursor, ProviderTableMeta.CAPABILITIES_USER_STATUS));
|
||||
capability.setUserStatusSupportsEmoji(
|
||||
getBoolean(cursor, ProviderTableMeta.CAPABILITIES_USER_STATUS_SUPPORTS_EMOJI));
|
||||
capability.setFilesLockingVersion(
|
||||
getString(cursor, ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION));
|
||||
}
|
||||
return capability;
|
||||
}
|
||||
|
@ -2258,22 +2161,6 @@ public class FileDataStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void saveVirtual(VirtualFolderType type, OCFile file) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.VIRTUAL_TYPE, type.toString());
|
||||
cv.put(ProviderTableMeta.VIRTUAL_OCFILE_ID, file.getFileId());
|
||||
|
||||
if (getContentResolver() != null) {
|
||||
getContentResolver().insert(ProviderTableMeta.CONTENT_URI_VIRTUAL, cv);
|
||||
} else {
|
||||
try {
|
||||
getContentProviderClient().insert(ProviderTableMeta.CONTENT_URI_VIRTUAL, cv);
|
||||
} catch (RemoteException e) {
|
||||
Log_OC.e(TAG, FAILED_TO_INSERT_MSG + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<OCFile> getAllGalleryItems() {
|
||||
return getGalleryItems(0, Long.MAX_VALUE);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.owncloud.android.R;
|
|||
import com.owncloud.android.lib.common.network.WebdavEntry;
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType;
|
||||
import com.owncloud.android.lib.resources.files.model.ServerFileInterface;
|
||||
import com.owncloud.android.lib.resources.shares.ShareeUser;
|
||||
import com.owncloud.android.utils.MimeType;
|
||||
|
@ -95,10 +96,23 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
String note;
|
||||
private List<ShareeUser> sharees;
|
||||
private String richWorkspace;
|
||||
private boolean locked;
|
||||
@Nullable
|
||||
private FileLockType lockType;
|
||||
@Nullable
|
||||
private String lockOwnerId;
|
||||
@Nullable
|
||||
private String lockOwnerDisplayName;
|
||||
@Nullable
|
||||
private String lockOwnerEditor;
|
||||
private long lockTimestamp;
|
||||
private long lockTimeout;
|
||||
@Nullable
|
||||
private String lockToken;
|
||||
|
||||
/**
|
||||
* URI to the local path of the file contents, if stored in the device; cached after first call
|
||||
* to {@link #getStorageUri()}
|
||||
* URI to the local path of the file contents, if stored in the device; cached after first call to {@link
|
||||
* #getStorageUri()}
|
||||
*/
|
||||
private Uri localUri;
|
||||
|
||||
|
@ -162,6 +176,14 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
richWorkspace = source.readString();
|
||||
previewAvailable = source.readInt() == 1;
|
||||
firstShareTimestamp = source.readLong();
|
||||
locked = source.readInt() == 1;
|
||||
lockType = FileLockType.fromValue(source.readInt());
|
||||
lockOwnerId = source.readString();
|
||||
lockOwnerDisplayName = source.readString();
|
||||
lockOwnerEditor = source.readString();
|
||||
lockTimestamp = source.readLong();
|
||||
lockTimeout = source.readLong();
|
||||
lockToken = source.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -196,6 +218,14 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
dest.writeString(richWorkspace);
|
||||
dest.writeInt(previewAvailable ? 1 : 0);
|
||||
dest.writeLong(firstShareTimestamp);
|
||||
dest.writeInt(locked ? 1 : 0);
|
||||
dest.writeInt(lockType != null ? lockType.getValue() : -1);
|
||||
dest.writeString(lockOwnerId);
|
||||
dest.writeString(lockOwnerDisplayName);
|
||||
dest.writeString(lockOwnerEditor);
|
||||
dest.writeLong(lockTimestamp);
|
||||
dest.writeLong(lockTimeout);
|
||||
dest.writeString(lockToken);
|
||||
}
|
||||
|
||||
public void setDecryptedRemotePath(String path) {
|
||||
|
@ -459,6 +489,14 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
mountType = WebdavEntry.MountType.INTERNAL;
|
||||
richWorkspace = "";
|
||||
firstShareTimestamp = 0;
|
||||
locked = false;
|
||||
lockType = null;
|
||||
lockOwnerId = null;
|
||||
lockOwnerDisplayName = null;
|
||||
lockOwnerEditor = null;
|
||||
lockTimestamp = 0;
|
||||
lockTimeout = 0;
|
||||
lockToken = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -831,4 +869,73 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
public void setFirstShareTimestamp(long firstShareTimestamp) {
|
||||
this.firstShareTimestamp = firstShareTimestamp;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FileLockType getLockType() {
|
||||
return lockType;
|
||||
}
|
||||
|
||||
public void setLockType(@Nullable FileLockType lockType) {
|
||||
this.lockType = lockType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLockOwnerId() {
|
||||
return lockOwnerId;
|
||||
}
|
||||
|
||||
public void setLockOwnerId(@Nullable String lockOwnerId) {
|
||||
this.lockOwnerId = lockOwnerId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLockOwnerDisplayName() {
|
||||
return lockOwnerDisplayName;
|
||||
}
|
||||
|
||||
public void setLockOwnerDisplayName(@Nullable String lockOwnerDisplayName) {
|
||||
this.lockOwnerDisplayName = lockOwnerDisplayName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLockOwnerEditor() {
|
||||
return lockOwnerEditor;
|
||||
}
|
||||
|
||||
public void setLockOwnerEditor(@Nullable String lockOwnerEditor) {
|
||||
this.lockOwnerEditor = lockOwnerEditor;
|
||||
}
|
||||
|
||||
public long getLockTimestamp() {
|
||||
return lockTimestamp;
|
||||
}
|
||||
|
||||
public void setLockTimestamp(long lockTimestamp) {
|
||||
this.lockTimestamp = lockTimestamp;
|
||||
}
|
||||
|
||||
public long getLockTimeout() {
|
||||
return lockTimeout;
|
||||
}
|
||||
|
||||
public void setLockTimeout(long lockTimeout) {
|
||||
this.lockTimeout = lockTimeout;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLockToken() {
|
||||
return lockToken;
|
||||
}
|
||||
|
||||
public void setLockToken(@Nullable String lockToken) {
|
||||
this.lockToken = lockToken;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.util.List;
|
|||
*/
|
||||
public class ProviderMeta {
|
||||
public static final String DB_NAME = "filelist";
|
||||
public static final int DB_VERSION = 62;
|
||||
public static final int DB_VERSION = 63;
|
||||
|
||||
private ProviderMeta() {
|
||||
// No instance
|
||||
|
@ -117,6 +117,14 @@ public class ProviderMeta {
|
|||
public static final String FILE_NOTE = "note";
|
||||
public static final String FILE_SHAREES = "sharees";
|
||||
public static final String FILE_RICH_WORKSPACE = "rich_workspace";
|
||||
public static final String FILE_LOCKED = "locked";
|
||||
public static final String FILE_LOCK_TYPE = "lock_type";
|
||||
public static final String FILE_LOCK_OWNER = "lock_owner";
|
||||
public static final String FILE_LOCK_OWNER_DISPLAY_NAME = "lock_owner_display_name";
|
||||
public static final String FILE_LOCK_OWNER_EDITOR = "lock_owner_editor";
|
||||
public static final String FILE_LOCK_TIMESTAMP = "lock_timestamp";
|
||||
public static final String FILE_LOCK_TIMEOUT = "lock_timeout";
|
||||
public static final String FILE_LOCK_TOKEN = "lock_token";
|
||||
|
||||
public static final List<String> FILE_ALL_COLUMNS = Collections.unmodifiableList(Arrays.asList(
|
||||
_ID,
|
||||
|
@ -153,8 +161,15 @@ public class ProviderMeta {
|
|||
FILE_OWNER_DISPLAY_NAME,
|
||||
FILE_NOTE,
|
||||
FILE_SHAREES,
|
||||
FILE_RICH_WORKSPACE));
|
||||
|
||||
FILE_RICH_WORKSPACE,
|
||||
FILE_LOCKED,
|
||||
FILE_LOCK_TYPE,
|
||||
FILE_LOCK_OWNER,
|
||||
FILE_LOCK_OWNER_DISPLAY_NAME,
|
||||
FILE_LOCK_OWNER_EDITOR,
|
||||
FILE_LOCK_TIMESTAMP,
|
||||
FILE_LOCK_TIMEOUT,
|
||||
FILE_LOCK_TOKEN));
|
||||
public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";
|
||||
|
||||
// Columns of ocshares table
|
||||
|
@ -210,6 +225,7 @@ public class ProviderMeta {
|
|||
public static final String CAPABILITIES_FILES_BIGFILECHUNKING = "files_bigfilechunking";
|
||||
public static final String CAPABILITIES_FILES_UNDELETE = "files_undelete";
|
||||
public static final String CAPABILITIES_FILES_VERSIONING = "files_versioning";
|
||||
public static final String CAPABILITIES_FILES_LOCKING_VERSION = "files_locking_version";
|
||||
public static final String CAPABILITIES_EXTERNAL_LINKS = "external_links";
|
||||
public static final String CAPABILITIES_SERVER_NAME = "server_name";
|
||||
public static final String CAPABILITIES_SERVER_COLOR = "server_color";
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
|
||||
package com.owncloud.android.files;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.nextcloud.android.files.FileLockingHelper;
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
|
@ -58,12 +60,13 @@ public class FileMenuFilter {
|
|||
private static final int SINGLE_SELECT_ITEMS = 1;
|
||||
public static final String SEND_OFF = "off";
|
||||
|
||||
private int numberOfAllFiles;
|
||||
private Collection<OCFile> files;
|
||||
private ComponentsGetter componentsGetter;
|
||||
private Context context;
|
||||
private boolean overflowMenu;
|
||||
private User user;
|
||||
private final int numberOfAllFiles;
|
||||
private final Collection<OCFile> files;
|
||||
private final ComponentsGetter componentsGetter;
|
||||
private final Context context;
|
||||
private final boolean overflowMenu;
|
||||
private final User user;
|
||||
private final String userId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -88,6 +91,10 @@ public class FileMenuFilter {
|
|||
this.context = context;
|
||||
this.overflowMenu = overflowMenu;
|
||||
this.user = user;
|
||||
userId = AccountManager
|
||||
.get(context)
|
||||
.getUserData(this.user.toPlatformAccount(),
|
||||
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,11 +132,23 @@ public class FileMenuFilter {
|
|||
filter(toShow, toHide, inSingleFileFragment);
|
||||
|
||||
for (int i : toShow) {
|
||||
showMenuItem(menu.findItem(i));
|
||||
final MenuItem item = menu.findItem(i);
|
||||
if (item != null) {
|
||||
showMenuItem(item);
|
||||
} else {
|
||||
// group
|
||||
menu.setGroupVisible(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i : toHide) {
|
||||
hideMenuItem(menu.findItem(i));
|
||||
final MenuItem item = menu.findItem(i);
|
||||
if (item != null) {
|
||||
hideMenuItem(item);
|
||||
} else {
|
||||
// group
|
||||
menu.setGroupVisible(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,11 +200,13 @@ public class FileMenuFilter {
|
|||
boolean synchronizing = anyFileSynchronizing();
|
||||
OCCapability capability = componentsGetter.getStorageManager().getCapability(user.getAccountName());
|
||||
boolean endToEndEncryptionEnabled = capability.getEndToEndEncryption().isTrue();
|
||||
boolean fileLockingEnabled = capability.getFilesLockingVersion() != null;
|
||||
|
||||
filterEdit(toShow, toHide, capability);
|
||||
filterDownload(toShow, toHide, synchronizing);
|
||||
filterRename(toShow, toHide, synchronizing);
|
||||
filterMoveCopy(toShow, toHide, synchronizing);
|
||||
filterCopy(toShow, toHide, synchronizing);
|
||||
filterMove(toShow, toHide, synchronizing);
|
||||
filterRemove(toShow, toHide, synchronizing);
|
||||
filterSelectAll(toShow, toHide, inSingleFileFragment);
|
||||
filterDeselectAll(toShow, toHide, inSingleFileFragment);
|
||||
|
@ -201,6 +222,9 @@ public class FileMenuFilter {
|
|||
filterUnsetEncrypted(toShow, toHide, endToEndEncryptionEnabled);
|
||||
filterSetPictureAs(toShow, toHide);
|
||||
filterStream(toShow, toHide);
|
||||
filterLock(toShow, toHide, fileLockingEnabled);
|
||||
filterUnlock(toShow, toHide, fileLockingEnabled);
|
||||
filterLockInfo(toShow, toHide, fileLockingEnabled);
|
||||
}
|
||||
|
||||
private void filterShareFile(List<Integer> toShow, List<Integer> toHide, OCCapability capability) {
|
||||
|
@ -252,9 +276,48 @@ public class FileMenuFilter {
|
|||
}
|
||||
}
|
||||
|
||||
private void filterLock(List<Integer> toShow, List<Integer> toHide, boolean fileLockingEnabled) {
|
||||
if (files.isEmpty() || !isSingleSelection() || !fileLockingEnabled) {
|
||||
toHide.add(R.id.action_lock_file);
|
||||
} else {
|
||||
OCFile file = files.iterator().next();
|
||||
if (file.isLocked() || file.isFolder()) {
|
||||
toHide.add(R.id.action_lock_file);
|
||||
} else {
|
||||
toShow.add(R.id.action_lock_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void filterUnlock(List<Integer> toShow, List<Integer> toHide, boolean fileLockingEnabled) {
|
||||
if (files.isEmpty() || !isSingleSelection() || !fileLockingEnabled) {
|
||||
toHide.add(R.id.action_unlock_file);
|
||||
} else {
|
||||
OCFile file = files.iterator().next();
|
||||
if (FileLockingHelper.canUserUnlockFile(userId, file)) {
|
||||
toShow.add(R.id.action_unlock_file);
|
||||
} else {
|
||||
toHide.add(R.id.action_unlock_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void filterLockInfo(List<Integer> toShow, List<Integer> toHide, boolean fileLockingEnabled) {
|
||||
if (files.isEmpty() || !isSingleSelection() || !fileLockingEnabled) {
|
||||
toHide.add(R.id.menu_group_lock_info);
|
||||
} else {
|
||||
OCFile file = files.iterator().next();
|
||||
if (file.isLocked()) {
|
||||
toShow.add(R.id.menu_group_lock_info);
|
||||
} else {
|
||||
toHide.add(R.id.menu_group_lock_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void filterEncrypt(List<Integer> toShow, List<Integer> toHide, boolean endToEndEncryptionEnabled) {
|
||||
if (files.isEmpty() || !isSingleSelection() || isSingleFile() || isEncryptedFolder()
|
||||
|| !endToEndEncryptionEnabled) {
|
||||
|| !endToEndEncryptionEnabled) {
|
||||
toHide.add(R.id.action_encrypted);
|
||||
} else {
|
||||
toShow.add(R.id.action_encrypted);
|
||||
|
@ -391,25 +454,32 @@ public class FileMenuFilter {
|
|||
}
|
||||
|
||||
private void filterRemove(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
||||
if (files.isEmpty() || synchronizing || containsEncryptedFolder()) {
|
||||
if (files.isEmpty() || synchronizing || containsEncryptedFolder() || containsLockedFile()) {
|
||||
toHide.add(R.id.action_remove_file);
|
||||
} else {
|
||||
toShow.add(R.id.action_remove_file);
|
||||
}
|
||||
}
|
||||
|
||||
private void filterMoveCopy(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
||||
if (files.isEmpty() || synchronizing || containsEncryptedFile() || containsEncryptedFolder()) {
|
||||
private void filterMove(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
||||
if (files.isEmpty() || synchronizing || containsEncryptedFile() || containsEncryptedFolder() || containsLockedFile()) {
|
||||
toHide.add(R.id.action_move);
|
||||
toHide.add(R.id.action_copy);
|
||||
} else {
|
||||
toShow.add(R.id.action_move);
|
||||
}
|
||||
}
|
||||
|
||||
private void filterCopy(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
||||
if (files.isEmpty() || synchronizing || containsEncryptedFile() || containsEncryptedFolder()) {
|
||||
toHide.add(R.id.action_copy);
|
||||
} else {
|
||||
toShow.add(R.id.action_copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void filterRename(Collection<Integer> toShow, Collection<Integer> toHide, boolean synchronizing) {
|
||||
if (!isSingleSelection() || synchronizing || containsEncryptedFile() || containsEncryptedFolder()) {
|
||||
if (!isSingleSelection() || synchronizing || containsEncryptedFile() || containsEncryptedFolder() || containsLockedFile()) {
|
||||
toHide.add(R.id.action_rename_file);
|
||||
} else {
|
||||
toShow.add(R.id.action_rename_file);
|
||||
|
@ -528,6 +598,15 @@ public class FileMenuFilter {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean containsLockedFile() {
|
||||
for (OCFile file : files) {
|
||||
if (file.isLocked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsEncryptedFolder() {
|
||||
for (OCFile file : files) {
|
||||
if (file.isFolder() && file.isEncrypted()) {
|
||||
|
|
|
@ -38,6 +38,7 @@ import android.widget.SeekBar;
|
|||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.utils.theme.ThemeBarUtils;
|
||||
|
@ -46,6 +47,8 @@ import com.owncloud.android.utils.theme.ThemeColorUtils;
|
|||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
/**
|
||||
* View containing controls for a {@link MediaPlayer}.
|
||||
|
@ -67,17 +70,18 @@ public class MediaControlView extends FrameLayout implements OnClickListener, On
|
|||
private ImageButton pauseButton;
|
||||
private ImageButton forwardButton;
|
||||
private ImageButton rewindButton;
|
||||
private final ThemeColorUtils themeColorUtils;
|
||||
private final ThemeBarUtils themeBarUtils;
|
||||
|
||||
@Inject
|
||||
ThemeColorUtils themeColorUtils;
|
||||
@Inject
|
||||
ThemeBarUtils themeBarUtils;
|
||||
|
||||
|
||||
public MediaControlView(Context context,
|
||||
AttributeSet attrs,
|
||||
ThemeColorUtils themeColorUtils,
|
||||
ThemeBarUtils themeBarUtils) {
|
||||
AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
this.themeColorUtils = themeColorUtils;
|
||||
this.themeBarUtils = themeBarUtils;
|
||||
MainApp.getAppComponent().inject(this);
|
||||
|
||||
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
|
|
|
@ -753,7 +753,15 @@ public class FileContentProvider extends ContentProvider {
|
|||
+ ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + TEXT
|
||||
+ ProviderTableMeta.FILE_NOTE + TEXT
|
||||
+ ProviderTableMeta.FILE_SHAREES + TEXT
|
||||
+ ProviderTableMeta.FILE_RICH_WORKSPACE + " TEXT);"
|
||||
+ ProviderTableMeta.FILE_RICH_WORKSPACE + TEXT
|
||||
+ ProviderTableMeta.FILE_LOCKED + INTEGER // boolean
|
||||
+ ProviderTableMeta.FILE_LOCK_TYPE + INTEGER
|
||||
+ ProviderTableMeta.FILE_LOCK_OWNER + TEXT
|
||||
+ ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME + TEXT
|
||||
+ ProviderTableMeta.FILE_LOCK_OWNER_EDITOR + TEXT
|
||||
+ ProviderTableMeta.FILE_LOCK_TIMESTAMP + INTEGER
|
||||
+ ProviderTableMeta.FILE_LOCK_TIMEOUT + INTEGER
|
||||
+ ProviderTableMeta.FILE_LOCK_TOKEN + " TEXT );"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -829,7 +837,8 @@ public class FileContentProvider extends ContentProvider {
|
|||
+ ProviderTableMeta.CAPABILITIES_DIRECT_EDITING_ETAG + TEXT
|
||||
+ ProviderTableMeta.CAPABILITIES_USER_STATUS + INTEGER
|
||||
+ ProviderTableMeta.CAPABILITIES_USER_STATUS_SUPPORTS_EMOJI + INTEGER
|
||||
+ ProviderTableMeta.CAPABILITIES_ETAG + " TEXT );");
|
||||
+ ProviderTableMeta.CAPABILITIES_ETAG + TEXT
|
||||
+ ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION + " TEXT );");
|
||||
}
|
||||
|
||||
private void createUploadsTable(SQLiteDatabase db) {
|
||||
|
@ -2454,6 +2463,39 @@ public class FileContentProvider extends ContentProvider {
|
|||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 63 && newVersion >= 63) {
|
||||
Log_OC.i(SQL, "Adding file locking columns");
|
||||
db.beginTransaction();
|
||||
try {
|
||||
// locking capabilities
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME + ADD_COLUMN + ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION + " TEXT ");
|
||||
// force refresh
|
||||
db.execSQL("UPDATE capabilities SET etag = '' WHERE 1=1");
|
||||
// locking properties
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCKED + " INTEGER "); // boolean
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_TYPE + " INTEGER ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_OWNER + " TEXT ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME + " TEXT ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_OWNER_EDITOR + " TEXT ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_TIMESTAMP + " INTEGER ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_TIMEOUT + " INTEGER ");
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_LOCK_TOKEN + " TEXT ");
|
||||
db.execSQL("UPDATE " + ProviderTableMeta.FILE_TABLE_NAME + " SET " + ProviderTableMeta.FILE_ETAG + " = '' WHERE 1=1");
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
if (!upgraded) {
|
||||
Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
|
||||
}
|
||||
|
|
|
@ -29,9 +29,12 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.utils.theme.ThemeColorUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
|
@ -40,22 +43,22 @@ import androidx.core.graphics.drawable.DrawableCompat;
|
|||
* Themeable switch preference TODO Migrate to androidx
|
||||
*/
|
||||
public class ThemeableSwitchPreference extends SwitchPreference {
|
||||
private ThemeColorUtils themeColorUtils;
|
||||
@Inject
|
||||
ThemeColorUtils themeColorUtils;
|
||||
|
||||
public ThemeableSwitchPreference(Context context) {
|
||||
super(context);
|
||||
MainApp.getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
public ThemeableSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
MainApp.getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
public ThemeableSwitchPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setThemeColorUtils(ThemeColorUtils themeColorUtils) {
|
||||
this.themeColorUtils = themeColorUtils;
|
||||
MainApp.getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -515,6 +515,7 @@ public class FileDisplayActivity extends FileActivity
|
|||
Log_OC.d(this, "Switch to oc file fragment");
|
||||
|
||||
setLeftFragment(new OCFileListFragment());
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
browseToRoot();
|
||||
}
|
||||
}
|
||||
|
@ -1551,14 +1552,10 @@ public class FileDisplayActivity extends FileActivity
|
|||
*/
|
||||
@VisibleForTesting
|
||||
public void lockScrolling() {
|
||||
final CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) binding.rootLayout.getLayoutParams();
|
||||
coordinatorParams.setBehavior(null);
|
||||
binding.rootLayout.setLayoutParams(coordinatorParams);
|
||||
binding.rootLayout.setNestedScrollingEnabled(false);
|
||||
binding.appbar.appbar.setExpanded(true, false);
|
||||
final AppBarLayout.LayoutParams appbarParams = (AppBarLayout.LayoutParams) binding.appbar.toolbarFrame.getLayoutParams();
|
||||
appbarParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL);
|
||||
binding.appbar.toolbarFrame.setLayoutParams(appbarParams);
|
||||
binding.appbar.appbar.setExpanded(true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1566,9 +1563,6 @@ public class FileDisplayActivity extends FileActivity
|
|||
*/
|
||||
@VisibleForTesting
|
||||
public void resetScrolling() {
|
||||
final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) binding.rootLayout.getLayoutParams();
|
||||
params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
|
||||
binding.rootLayout.setLayoutParams(params);
|
||||
AppBarLayout.LayoutParams appbarParams = (AppBarLayout.LayoutParams) binding.appbar.toolbarFrame.getLayoutParams();
|
||||
appbarParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
|
||||
binding.appbar.toolbarFrame.setLayoutParams(appbarParams);
|
||||
|
|
|
@ -540,7 +540,6 @@ public class SettingsActivity extends ThemedPreferenceActivity
|
|||
boolean fShowMediaScanNotifications) {
|
||||
ThemeableSwitchPreference mShowMediaScanNotifications =
|
||||
(ThemeableSwitchPreference) findPreference(PREFERENCE_SHOW_MEDIA_SCAN_NOTIFICATIONS);
|
||||
mShowMediaScanNotifications.setThemeColorUtils(themeColorUtils);
|
||||
|
||||
if (fShowMediaScanNotifications) {
|
||||
preferenceCategoryDetails.removePreference(mShowMediaScanNotifications);
|
||||
|
@ -550,7 +549,6 @@ public class SettingsActivity extends ThemedPreferenceActivity
|
|||
private void setupHiddenFilesPreference(PreferenceCategory preferenceCategoryDetails,
|
||||
boolean fShowHiddenFilesEnabled) {
|
||||
showHiddenFiles = (ThemeableSwitchPreference) findPreference("show_hidden_files");
|
||||
showHiddenFiles.setThemeColorUtils(themeColorUtils);
|
||||
if (fShowHiddenFilesEnabled) {
|
||||
showHiddenFiles.setOnPreferenceClickListener(preference -> {
|
||||
preferences.setShowHiddenFilesEnabled(showHiddenFiles.isChecked());
|
||||
|
@ -617,10 +615,6 @@ public class SettingsActivity extends ThemedPreferenceActivity
|
|||
preferenceCategorySyncedFolders.setTitle(themeTextUtils.getColoredTitle(getString(R.string.drawer_synced_folders),
|
||||
accentColor));
|
||||
|
||||
ThemeableSwitchPreference syncedFolderOnWifiSwitch =
|
||||
(ThemeableSwitchPreference) findPreference("synced_folder_on_wifi");
|
||||
syncedFolderOnWifiSwitch.setThemeColorUtils(themeColorUtils);
|
||||
|
||||
if (!getResources().getBoolean(R.bool.syncedFolder_light)) {
|
||||
preferenceScreen.removePreference(preferenceCategorySyncedFolders);
|
||||
} else {
|
||||
|
|
|
@ -466,6 +466,12 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
holder.getOverflowMenu().setOnClickListener(view -> ocFileListFragmentInterface
|
||||
.onOverflowIconClicked(file, view));
|
||||
}
|
||||
|
||||
if (file.isLocked()) {
|
||||
holder.getOverflowMenu().setImageResource(R.drawable.ic_locked_dots_small);
|
||||
} else {
|
||||
holder.getOverflowMenu().setImageResource(R.drawable.ic_dots_vertical);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindListGridItemViewHolder(ListGridItemViewHolder holder, OCFile file) {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.ui.events
|
||||
|
||||
data class FileLockEvent(val filePath: String, val shouldLock: Boolean)
|
|
@ -41,13 +41,15 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.behavior.HideBottomViewOnScrollBehavior;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.nextcloud.android.files.FileLockingMenuCustomization;
|
||||
import com.nextcloud.android.files.ThemedPopupMenu;
|
||||
import com.nextcloud.android.lib.resources.files.ToggleFileLockRemoteOperation;
|
||||
import com.nextcloud.android.lib.richWorkspace.RichWorkspaceDirectEditingRemoteOperation;
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.nextcloud.client.account.UserAccountManager;
|
||||
|
@ -56,6 +58,7 @@ import com.nextcloud.client.di.Injectable;
|
|||
import com.nextcloud.client.network.ClientFactory;
|
||||
import com.nextcloud.client.preferences.AppPreferences;
|
||||
import com.nextcloud.client.utils.Throttler;
|
||||
import com.nextcloud.common.NextcloudClient;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
|
@ -92,6 +95,7 @@ import com.owncloud.android.ui.events.ChangeMenuEvent;
|
|||
import com.owncloud.android.ui.events.CommentsEvent;
|
||||
import com.owncloud.android.ui.events.EncryptionEvent;
|
||||
import com.owncloud.android.ui.events.FavoriteEvent;
|
||||
import com.owncloud.android.ui.events.FileLockEvent;
|
||||
import com.owncloud.android.ui.events.SearchEvent;
|
||||
import com.owncloud.android.ui.helpers.FileOperationsHelper;
|
||||
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
|
||||
|
@ -181,6 +185,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
private static final String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
|
||||
private static final String DIALOG_CREATE_DOCUMENT = "DIALOG_CREATE_DOCUMENT";
|
||||
private static final String DIALOG_BOTTOM_SHEET = "DIALOG_BOTTOM_SHEET";
|
||||
private static final String DIALOG_LOCK_DETAILS = "DIALOG_LOCK_DETAILS";
|
||||
|
||||
private static final int SINGLE_SELECTION = 1;
|
||||
private static final int NOT_ENOUGH_SPACE_FRAG_REQUEST_CODE = 2;
|
||||
|
@ -568,7 +573,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
@Override
|
||||
public void onOverflowIconClicked(OCFile file, View view) {
|
||||
throttler.run("overflowClick", () -> {
|
||||
PopupMenu popup = new PopupMenu(getActivity(), view);
|
||||
final ThemedPopupMenu popup = new ThemedPopupMenu(requireContext(), view);
|
||||
popup.inflate(R.menu.item_file);
|
||||
FileMenuFilter mf = new FileMenuFilter(mAdapter.getFiles().size(),
|
||||
Collections.singleton(file),
|
||||
|
@ -576,11 +581,13 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
true,
|
||||
accountManager.getUser());
|
||||
mf.filter(popup.getMenu(), true);
|
||||
new FileLockingMenuCustomization(requireContext()).customizeMenu(popup.getMenu(), file);
|
||||
popup.setOnMenuItemClickListener(item -> {
|
||||
Set<OCFile> checkedFiles = new HashSet<>();
|
||||
checkedFiles.add(file);
|
||||
return onFileActionChosen(item, checkedFiles);
|
||||
});
|
||||
|
||||
popup.show();
|
||||
});
|
||||
}
|
||||
|
@ -589,7 +596,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
public void newDocument() {
|
||||
ChooseRichDocumentsTemplateDialogFragment.newInstance(mFile,
|
||||
ChooseRichDocumentsTemplateDialogFragment.Type.DOCUMENT)
|
||||
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
||||
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -603,7 +610,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
public void newPresentation() {
|
||||
ChooseRichDocumentsTemplateDialogFragment.newInstance(mFile,
|
||||
ChooseRichDocumentsTemplateDialogFragment.Type.PRESENTATION)
|
||||
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
||||
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -616,7 +623,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
@Override
|
||||
public void showTemplate(Creator creator, String headline) {
|
||||
ChooseTemplateDialogFragment.newInstance(mFile, creator, headline).show(requireActivity().getSupportFragmentManager(),
|
||||
DIALOG_CREATE_DOCUMENT);
|
||||
DIALOG_CREATE_DOCUMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -741,6 +748,9 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
// Determine if we need to finish the action mode because there are no items selected
|
||||
if (checkedCount == 0 && !mIsActionModeNew) {
|
||||
exitSelectionMode();
|
||||
} else if (checkedCount == 1) {
|
||||
// customize for locking if file is locked
|
||||
new FileLockingMenuCustomization(requireContext()).customizeMenu(menu, checkedFiles.iterator().next());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1146,6 +1156,10 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
} else if (itemId == R.id.action_unset_encrypted) {
|
||||
mContainerActivity.getFileOperationsHelper().toggleEncryption(singleFile, false);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_lock_file) {
|
||||
mContainerActivity.getFileOperationsHelper().toggleFileLock(singleFile, true);
|
||||
} else if (itemId == R.id.action_unlock_file) {
|
||||
mContainerActivity.getFileOperationsHelper().toggleFileLock(singleFile, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1192,6 +1206,8 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
} else if (itemId == R.id.action_send_file) {
|
||||
mContainerActivity.getFileOperationsHelper().sendFiles(checkedFiles);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_lock_file) {
|
||||
// TODO call lock API
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1642,6 +1658,35 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||
public void onMessageEvent(FileLockEvent event) {
|
||||
final User user = accountManager.getUser();
|
||||
|
||||
try {
|
||||
new Handler(Looper.getMainLooper()).post(() -> setLoading(true));
|
||||
NextcloudClient client = clientFactory.createNextcloudClient(user);
|
||||
ToggleFileLockRemoteOperation operation = new ToggleFileLockRemoteOperation(event.getShouldLock(), event.getFilePath());
|
||||
RemoteOperationResult<Void> result = operation.execute(client);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
// TODO only refresh the modified file?
|
||||
new Handler(Looper.getMainLooper()).post(this::onRefresh);
|
||||
} else {
|
||||
Snackbar.make(getRecyclerView(),
|
||||
R.string.error_file_lock,
|
||||
Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
} catch (ClientFactory.CreationException e) {
|
||||
Log_OC.e(TAG, "Cannot create client", e);
|
||||
Snackbar.make(getRecyclerView(),
|
||||
R.string.error_file_lock,
|
||||
Snackbar.LENGTH_LONG).show();
|
||||
} finally {
|
||||
new Handler(Looper.getMainLooper()).post(() -> setLoading(false));
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTitle(@StringRes final int title) {
|
||||
setTitle(getContext().getString(title));
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ import com.owncloud.android.ui.dialog.SendFilesDialog;
|
|||
import com.owncloud.android.ui.dialog.SendShareDialog;
|
||||
import com.owncloud.android.ui.events.EncryptionEvent;
|
||||
import com.owncloud.android.ui.events.FavoriteEvent;
|
||||
import com.owncloud.android.ui.events.FileLockEvent;
|
||||
import com.owncloud.android.ui.events.SyncEventFinished;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
|
@ -918,6 +919,12 @@ public class FileOperationsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public void toggleFileLock(OCFile file, boolean shouldBeLocked) {
|
||||
if (file.isLocked() != shouldBeLocked) {
|
||||
EventBus.getDefault().post(new FileLockEvent(file.getRemotePath(), shouldBeLocked));
|
||||
}
|
||||
}
|
||||
|
||||
public void renameFile(OCFile file, String newFilename) {
|
||||
// RenameFile
|
||||
Intent service = new Intent(fileActivity, OperationsService.class);
|
||||
|
|
|
@ -233,6 +233,14 @@ public final class FileStorageUtils {
|
|||
file.setNote(remote.getNote());
|
||||
file.setSharees(new ArrayList<>(Arrays.asList(remote.getSharees())));
|
||||
file.setRichWorkspace(remote.getRichWorkspace());
|
||||
file.setLocked(remote.isLocked());
|
||||
file.setLockType(remote.getLockType());
|
||||
file.setLockOwnerId(remote.getLockOwner());
|
||||
file.setLockOwnerDisplayName(remote.getLockOwnerDisplayName());
|
||||
file.setLockOwnerEditor(remote.getLockOwnerEditor());
|
||||
file.setLockTimestamp(remote.getLockTimestamp());
|
||||
file.setLockTimeout(remote.getLockTimeout());
|
||||
file.setLockToken(remote.getLockToken());
|
||||
|
||||
return file;
|
||||
}
|
||||
|
|
25
app/src/main/res/color/menu_item_text_color.xml
Normal file
25
app/src/main/res/color/menu_item_text_color.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Nextcloud Android client application
|
||||
~
|
||||
~ @author Álvaro Brey Vilas
|
||||
~ Copyright (C) 2022 Álvaro Brey Vilas
|
||||
~ Copyright (C) 2022 Nextcloud GmbH
|
||||
~
|
||||
~ This program 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.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU 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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/text_color" android:state_enabled="true"/>
|
||||
<item android:color="@color/disabled_text" />
|
||||
</selector>
|
33
app/src/main/res/drawable/ic_locked_dots_small.xml
Normal file
33
app/src/main/res/drawable/ic_locked_dots_small.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!--
|
||||
~ Nextcloud Android client application
|
||||
~
|
||||
~ @author Álvaro Brey Vilas
|
||||
~ Copyright (C) 2022 Álvaro Brey Vilas
|
||||
~ Copyright (C) 2022 Nextcloud GmbH
|
||||
~
|
||||
~ This program 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.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU 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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="m7.9482,15.6104c0.3479,0 0.682,-0.1385 0.9282,-0.3847 0.2462,-0.2462 0.3847,-0.5803 0.3847,-0.9282 0,-0.7286 -0.5908,-1.3129 -1.3129,-1.3129 -0.3479,0 -0.682,0.1385 -0.9282,0.3847 -0.2462,0.2462 -0.3847,0.5803 -0.3847,0.9282 0,0.3479 0.1385,0.682 0.3847,0.9282 0.2462,0.2462 0.5803,0.3847 0.9282,0.3847M11.8868,9.7025c0.3479,0 0.682,0.1385 0.9282,0.3847 0.2462,0.2462 0.3847,0.5803 0.3847,0.9282v6.5644c0,0.3479 -0.1385,0.682 -0.3847,0.9282 -0.2462,0.2462 -0.5803,0.3847 -0.9282,0.3847H4.0095c-0.3479,0 -0.682,-0.1385 -0.9282,-0.3847 -0.2462,-0.2462 -0.3847,-0.5803 -0.3847,-0.9282v-6.5644c0,-0.7286 0.5908,-1.3129 1.3129,-1.3129H4.666V8.3896c0,-0.8704 0.3459,-1.7054 0.961,-2.3212 0.6157,-0.6151 1.4507,-0.961 2.3212,-0.961 0.8704,0 1.7054,0.3459 2.3212,0.961 0.6151,0.6157 0.961,1.4507 0.961,2.3212v1.3129h0.6564M7.9482,6.4203c-0.5219,0 -1.0234,0.2074 -1.3923,0.577C6.1863,7.3662 5.9789,7.8677 5.9789,8.3896V9.7025H9.9175V8.3896c0,-0.5219 -0.2074,-1.0234 -0.577,-1.3923C8.9716,6.6277 8.47,6.4203 7.9482,6.4203Z"
|
||||
android:strokeWidth="0.656438"
|
||||
android:fillColor="#666666"/>
|
||||
<path
|
||||
android:pathData="m19.3033,8c1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2zM19.3033,10c-1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2zM19.3033,16c-1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2z"
|
||||
android:fillColor="#666666"/>
|
||||
</vector>
|
|
@ -26,7 +26,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
tools:context=".ui.preview.PreviewMediaFragment">
|
||||
|
||||
<ImageView
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ListItemLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/standard_list_item_size"
|
||||
|
@ -137,10 +138,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical|end"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:paddingEnd="@dimen/zero">
|
||||
|
||||
|
@ -148,7 +150,6 @@
|
|||
android:id="@+id/unreadComments"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/unread_comments"
|
||||
android:focusable="true"
|
||||
|
@ -161,8 +162,6 @@
|
|||
android:id="@+id/sharedIcon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/unreadComments"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/shared_icon_share"
|
||||
android:focusable="true"
|
||||
|
@ -173,10 +172,8 @@
|
|||
<com.owncloud.android.ui.AvatarGroupLayout
|
||||
android:id="@+id/sharedAvatars"
|
||||
android:layout_width="100dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="@dimen/file_icon_size"
|
||||
android:layout_alignEnd="@id/sharedIcon"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/sharedIcon"
|
||||
android:contentDescription="@string/shared_avatar_desc"
|
||||
android:visibility="visible" />
|
||||
|
||||
|
@ -184,8 +181,6 @@
|
|||
android:id="@+id/custom_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/sharedAvatars"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/checkbox"
|
||||
android:focusable="false"
|
||||
|
@ -197,8 +192,6 @@
|
|||
android:id="@+id/overflow_menu"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/custom_checkbox"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/overflow_menu"
|
||||
android:focusable="true"
|
||||
|
@ -206,5 +199,5 @@
|
|||
android:paddingEnd="12dp"
|
||||
android:src="@drawable/ic_dots_vertical" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/appbar"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
|
||||
android:theme="@style/Theme.ToolbarWithDisabled"
|
||||
app:popupTheme="@style/Theme.AppCompat.DayNight.NoActionBar"
|
||||
tools:visibility="gone">
|
||||
|
||||
|
|
|
@ -18,9 +18,40 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="AppCompatResource">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="AppCompatResource">
|
||||
|
||||
<group
|
||||
android:id="@+id/menu_group_lock_info"
|
||||
android:visible="false"
|
||||
android:enabled="false"
|
||||
tools:visible="true">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_locked_by"
|
||||
android:showAsAction="never"
|
||||
android:title="Locked by %1$s"
|
||||
android:enabled="false"
|
||||
app:showAsAction="never"
|
||||
tools:ignore="HardcodedText"
|
||||
tools:title="Locked by Username With Surname at bla bla bla bla bla" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_locked_until"
|
||||
android:showAsAction="never"
|
||||
android:enabled="false"
|
||||
android:title="Lock expires: %1$s"
|
||||
app:showAsAction="never"
|
||||
tools:ignore="HardcodedText"
|
||||
tools:title="Lock expires: in 20 minutes" />
|
||||
</group>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_unlock_file"
|
||||
android:showAsAction="never"
|
||||
android:title="@string/unlock_file"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
|
@ -46,6 +77,12 @@
|
|||
app:showAsAction="never"
|
||||
android:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_lock_file"
|
||||
android:showAsAction="never"
|
||||
android:title="@string/lock_file"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_rename_file"
|
||||
android:title="@string/common_rename"
|
||||
|
|
|
@ -396,6 +396,7 @@
|
|||
<string name="local_file_not_found_message">ملف غير موجود في نظام الملفات المحلي</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">لا توجد مجلدات أخرى.</string>
|
||||
<string name="lock_file">أقفل الملف</string>
|
||||
<string name="log_send_mail_subject">%1$s سجلات تطبيق الأندرويد</string>
|
||||
<string name="log_send_no_mail_app">لا يوجد تطبيق لارسال السجلات . الرجاء تثبيت عميل البريد الالكتروني.</string>
|
||||
<string name="login">تسجيل الدخول</string>
|
||||
|
@ -755,6 +756,7 @@
|
|||
<string name="trashbin_file_not_restored">الملف %1$s لا يمكن إسترجاعه!</string>
|
||||
<string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string>
|
||||
<string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string>
|
||||
<string name="unlock_file">فتح قفل الملف</string>
|
||||
<string name="unread_comments">توجد تعليقات غير مقروءة</string>
|
||||
<string name="unset_encrypted">لم يتم تحديد التشفير</string>
|
||||
<string name="unset_favorite">إزالتها مِن المفضلة</string>
|
||||
|
|
|
@ -402,6 +402,7 @@
|
|||
<string name="local_file_not_found_message">Файлът не е намерен в локалната система за файлове</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Няма повече папки.</string>
|
||||
<string name="lock_file">Заключване на файл</string>
|
||||
<string name="log_send_mail_subject">%1$s журнали от Android приложението</string>
|
||||
<string name="log_send_no_mail_app">Няма намерено приложение за изпращане на журнали. Моля, инсталирайте имейл клиент.</string>
|
||||
<string name="login">Вписване</string>
|
||||
|
@ -757,6 +758,7 @@
|
|||
<string name="trashbin_file_not_restored">Файлът %1$s не може да бъде възстановен!</string>
|
||||
<string name="trashbin_loading_failed">Зареждането на кошчето е неуспешно!</string>
|
||||
<string name="trashbin_not_emptied">Файловете не могат да бъдат окончателно изтрити!</string>
|
||||
<string name="unlock_file">Отключване на файл</string>
|
||||
<string name="unread_comments">Съществуват непрочетени коментари</string>
|
||||
<string name="unset_encrypted">Изключи криптиране</string>
|
||||
<string name="unset_favorite">Премахни от любимите</string>
|
||||
|
|
|
@ -356,6 +356,7 @@
|
|||
<string name="local_file_not_found_message">N\'ez eus restr ebet kavet e restroù diabarzh ar sistem</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">N\'ez eus teuliad all ebet</string>
|
||||
<string name="lock_file">Prennan ar restr</string>
|
||||
<string name="log_send_mail_subject">%1$s kazetenn meziant Android</string>
|
||||
<string name="login">kennaskañ</string>
|
||||
<string name="logs_menu_delete">Lemel ar gazetennoù</string>
|
||||
|
@ -664,6 +665,7 @@
|
|||
<string name="trashbin_file_not_deleted">Ar restr %1$s n\'eo ket evit bezhaãn lamet !</string>
|
||||
<string name="trashbin_file_not_restored">Ar restr %1$s n\'eo ket evit bezha adlakaet !</string>
|
||||
<string name="trashbin_not_emptied">N\'eo ket posupl lemel ar restr da virviken !</string>
|
||||
<string name="unlock_file">Dibrennan ar restr</string>
|
||||
<string name="unread_comments">Bez eez eus kemenadennom n\'int ket bet lennet</string>
|
||||
<string name="unset_encrypted">Lemel ar sifrañ</string>
|
||||
<string name="unset_favorite">Lemel eus ar pennroll</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">No s\'ha trobat el fitxer al sistema de fitxers local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">No hi ha més carpetes.</string>
|
||||
<string name="lock_file">Bloca el fitxer</string>
|
||||
<string name="log_send_mail_subject">%1$s registres de la aplicació d\'Android.</string>
|
||||
<string name="log_send_no_mail_app">No s\'ha trobat cap aplicació per enviar els registres. Instal·leu un client de correu electrònic.</string>
|
||||
<string name="login">Inicia la sessió</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">El fitxer %1$s no es pot restaurar!</string>
|
||||
<string name="trashbin_loading_failed">No s\'ha pogut carregar la paperera!</string>
|
||||
<string name="trashbin_not_emptied">Els fitxers no es poden suprimir permanentment!</string>
|
||||
<string name="unlock_file">Desbloca el fitxer</string>
|
||||
<string name="unread_comments">Hi ha comentaris sense llegir</string>
|
||||
<string name="unset_encrypted">Desactiva el xifrat</string>
|
||||
<string name="unset_favorite">Suprimeix-ho de preferits</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">Chyba při přidávání komentáře k souboru</string>
|
||||
<string name="error_crash_title">%1$s zhavarovalo</string>
|
||||
<string name="error_creating_file_from_template">Chyba při vytváření souboru ze šablony</string>
|
||||
<string name="error_file_lock">Chyba při změně stavu zámku souboru</string>
|
||||
<string name="error_report_issue_action">Hlášení</string>
|
||||
<string name="error_report_issue_text">Nahlásit problém? (vyžaduje GitHub účet)</string>
|
||||
<string name="error_retrieving_file">Chyba při získávání souboru</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">Soubor nenalezen na souborovém systému</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Nejsou zde žádné další složky.</string>
|
||||
<string name="lock_expiration_info">Platnost skončí: %1$s</string>
|
||||
<string name="lock_file">Zamknout soubor</string>
|
||||
<string name="locked_by">Uzamkl(a) %1$s</string>
|
||||
<string name="locked_by_app">Uzamčeno aplikací %1$s</string>
|
||||
<string name="log_send_mail_subject">Záznamy událostí v aplikaci %1$s pro Android</string>
|
||||
<string name="log_send_no_mail_app">Nebyla nalezena žádná aplikace, přes kterou by bylo možné odeslat záznamy událostí. Nainstalujte si e-mailového klienta.</string>
|
||||
<string name="login">Přihlásit</string>
|
||||
|
@ -777,6 +782,7 @@ Jak vývojová tak produkční verze je k dispozici na F-droid a mohou být nain
|
|||
<string name="trashbin_file_not_restored">Soubor %1$s se nepodařilo obnovit!</string>
|
||||
<string name="trashbin_loading_failed">Načtení obsahu koše se nezdařilo!</string>
|
||||
<string name="trashbin_not_emptied">Soubory se nepodařilo natrvalo smazat!</string>
|
||||
<string name="unlock_file">Odemknout soubor</string>
|
||||
<string name="unread_comments">Existuje nepřečtený komentář</string>
|
||||
<string name="unset_encrypted">Zrušit šifrování</string>
|
||||
<string name="unset_favorite">Odebrat z oblíbených</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Fil ikke fundet i lokalt filsystem</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Der er ikke flere mapper.</string>
|
||||
<string name="lock_file">Lås filen</string>
|
||||
<string name="log_send_mail_subject">%1$s Android-app - logge</string>
|
||||
<string name="log_send_no_mail_app">Der er ingen app tilgængelig til at sende log filer. Venligst installér en email klient.</string>
|
||||
<string name="login">Log ind</string>
|
||||
|
@ -758,6 +759,7 @@ Enheds legitimationsoplysninger er sat op
|
|||
<string name="trashbin_file_not_restored">Fil %1$s kunne ikke genskabes!</string>
|
||||
<string name="trashbin_loading_failed">Indlæsning af papirkurv mislykkedes!</string>
|
||||
<string name="trashbin_not_emptied">Filer kunne ikke permanent slettes!</string>
|
||||
<string name="unlock_file">Lås op filen</string>
|
||||
<string name="unread_comments">Der er ulæste kommentarer</string>
|
||||
<string name="unset_encrypted">Slå kryptering fra</string>
|
||||
<string name="unset_favorite">Fjern fra favoritter</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">Fehler beim Kommentieren der Datei</string>
|
||||
<string name="error_crash_title">%1$s abgestürzt</string>
|
||||
<string name="error_creating_file_from_template">Fehler beim Erzeugen einer Datei aus der Vorlage</string>
|
||||
<string name="error_file_lock">Fehler beim Ändern des Sperr-Status</string>
|
||||
<string name="error_report_issue_action">Melden</string>
|
||||
<string name="error_report_issue_text">Problem melden? (benötigt ein GitHub-Konto)</string>
|
||||
<string name="error_retrieving_file">Fehler beim Abruf der Datei</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">Die Datei wurde im lokalen Dateisystem nicht gefunden</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Hier gibt es keine weiteren Ordner.</string>
|
||||
<string name="lock_expiration_info">Läuft ab: %1$s</string>
|
||||
<string name="lock_file">Datei sperren</string>
|
||||
<string name="locked_by">Gesperrt von %1$s</string>
|
||||
<string name="locked_by_app">Gesperrt von der App %1$s</string>
|
||||
<string name="log_send_mail_subject">%1$s Android-App Meldungen</string>
|
||||
<string name="log_send_no_mail_app">Keine App zum Senden von Protokolldateien gefunden. Bitte installieren Sie einen E-Mail-Client.</string>
|
||||
<string name="login">Anmelden</string>
|
||||
|
@ -757,6 +762,7 @@
|
|||
<string name="trashbin_file_not_restored">Datei %1$s konnte nicht wiederhergestellt werden!</string>
|
||||
<string name="trashbin_loading_failed">Laden des Papierkorbs fehlgeschlagen!</string>
|
||||
<string name="trashbin_not_emptied">Dateien konnten nicht endgültig gelöscht werden!</string>
|
||||
<string name="unlock_file">Datei entsperren</string>
|
||||
<string name="unread_comments">Es gibt ungelesene Kommentare</string>
|
||||
<string name="unset_encrypted">Verschlüsselung aufheben</string>
|
||||
<string name="unset_favorite">Aus den Favoriten entfernen</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Το αρχείο δεν βρέθηκε στο τοπικό σύστημα αρχείων</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Δεν υπάρχουν άλλοι φάκελοι.</string>
|
||||
<string name="lock_file">Κλείδωμα αρχείου</string>
|
||||
<string name="log_send_mail_subject">%1$s ιστορικό της εφαρμογής Android</string>
|
||||
<string name="log_send_no_mail_app">Δεν βρέθηκε εφαρμογή για αποστολή αρχείων καταγραφής. Εγκαταστήστε ένα πρόγραμμα -πελάτη ηλεκτρονικής αλληλογραφίας.</string>
|
||||
<string name="login">Είσοδος</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">Το αρχείο %1$s δεν μπορεί να ανακτηθεί!</string>
|
||||
<string name="trashbin_loading_failed">Αποτυχία φόρτωσης κάδου ανακύκλωσης!</string>
|
||||
<string name="trashbin_not_emptied">Τα αρχεία δεν θα διαγραφούν μόνιμα!</string>
|
||||
<string name="unlock_file">Ξεκλείδωμα αρχείου</string>
|
||||
<string name="unread_comments">Υπάρχουν μη αναγνωσμένα σχόλια</string>
|
||||
<string name="unset_encrypted">Χρήση κρυπτογράφησης</string>
|
||||
<string name="unset_favorite">Αφαίρεση από τα αγαπημένα</string>
|
||||
|
|
|
@ -398,6 +398,7 @@
|
|||
<string name="local_file_not_found_message">El archivo no se encuentra en el sistema de archivos local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">No hay mas carpetas</string>
|
||||
<string name="lock_file">Bloquear archivo</string>
|
||||
<string name="log_send_mail_subject">Se han encontrado %1$s aplicaciones de registros para Android</string>
|
||||
<string name="log_send_no_mail_app">No se ha encontrado una app para enviar los registros. Por favor, instale un cliente de correo electrónico.</string>
|
||||
<string name="login">Iniciar sesión</string>
|
||||
|
@ -751,6 +752,7 @@
|
|||
<string name="trashbin_file_not_restored">No se ha podido restaurar el archivo %1$s.</string>
|
||||
<string name="trashbin_loading_failed">¡Fallo al cargar la papelera!</string>
|
||||
<string name="trashbin_not_emptied">No se ha podido eliminar permanentemente el archivo.</string>
|
||||
<string name="unlock_file">Desbloquear archivo</string>
|
||||
<string name="unread_comments">Hay comentarios no leídos</string>
|
||||
<string name="unset_encrypted">Desactivar cifrado</string>
|
||||
<string name="unset_favorite">Quitar de favoritos</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">Errorea fitxategia iruzkintzean</string>
|
||||
<string name="error_crash_title">%1$s(e)k huts egin du</string>
|
||||
<string name="error_creating_file_from_template">Errorea fitxategia plantilatik sortzerakoan</string>
|
||||
<string name="error_file_lock">Errorea fitxategiaren blokeo egoera aldatzean</string>
|
||||
<string name="error_report_issue_action">Jakinarazi</string>
|
||||
<string name="error_report_issue_text">Arazoaren berri eman nahi duzu? (GitHub kontu bat beharrezkoa da)</string>
|
||||
<string name="error_retrieving_file">Errorea fitxategia berreskuratzean</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">Ez da fitxategia topatu fitxategi-sistema lokalean</string>
|
||||
<string name="local_folder_friendly_path">%2$s(e)tik %1$s</string>
|
||||
<string name="local_folder_list_empty">Ez dago karpeta gehiagorik.</string>
|
||||
<string name="lock_expiration_info">Iraungitze data: %1$s</string>
|
||||
<string name="lock_file">Blokeatu fitxategia</string>
|
||||
<string name="locked_by">%1$s-(e)k blokeatuta</string>
|
||||
<string name="locked_by_app">%1$s aplikazioak blokeatuta</string>
|
||||
<string name="log_send_mail_subject">%1$s Android aplikazioaren egunkariak</string>
|
||||
<string name="log_send_no_mail_app">Ez da aurkitu egunkariak bidaltzeko aplikaziorik. Instalatu posta elektroniko bezero bat.</string>
|
||||
<string name="login">Hasi saioa</string>
|
||||
|
@ -756,6 +761,7 @@
|
|||
<string name="trashbin_file_not_restored"> %1$s fitxategia ezin da berreskuratu!</string>
|
||||
<string name="trashbin_loading_failed">Zakarrontzia kargatzeak huts egin du!</string>
|
||||
<string name="trashbin_not_emptied">Fitxategiak ezin dira betirako ezabatu!</string>
|
||||
<string name="unlock_file">Desblokeatu fitxategia</string>
|
||||
<string name="unread_comments">Irakurri gabeko iruzkinak daude</string>
|
||||
<string name="unset_encrypted">Kendu enkriptatzea</string>
|
||||
<string name="unset_favorite">Gogokoenetatik kendu</string>
|
||||
|
|
|
@ -372,6 +372,7 @@
|
|||
<string name="local_file_not_found_message">فایل در فایلهای سیستمی محلی یافت نشد</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">هیچ پوشه ای وجود ندارد</string>
|
||||
<string name="lock_file">قفل کردن پرونده</string>
|
||||
<string name="log_send_mail_subject">%1$s لاگهای برنامه های اندروید</string>
|
||||
<string name="log_send_no_mail_app">برنامهای برای فرستادن گزارشها پیدا نشد. لطفا یک کارخواه رایانامه نصب کنید.</string>
|
||||
<string name="login">Log in</string>
|
||||
|
@ -705,6 +706,7 @@
|
|||
<string name="trashbin_file_not_restored">فایل %1$s نمی تواند بازیابی شود</string>
|
||||
<string name="trashbin_loading_failed">بار کردن سطل زباله شکست خورد!</string>
|
||||
<string name="trashbin_not_emptied">نمی توان پرونده ها را برای همیشه حذف کرد!</string>
|
||||
<string name="unlock_file">باز کردن قفل پرونده</string>
|
||||
<string name="unread_comments">نظرات خوانده نشده وجود دارد</string>
|
||||
<string name="unset_encrypted">به صورت رمزگذاری شده تنظیم نشده است</string>
|
||||
<string name="unset_favorite">حذف از موارد دلخواه</string>
|
||||
|
|
|
@ -395,6 +395,7 @@
|
|||
<string name="local_file_not_found_message">Tiedostoa ei löytynyt paikallisesta tiedostojärjestelmästä</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Kansioita ei ole enempää.</string>
|
||||
<string name="lock_file">Lukitse tiedosto</string>
|
||||
<string name="log_send_mail_subject">%1$sin Android-sovelluksen lokit</string>
|
||||
<string name="log_send_no_mail_app">Sovellusta ei löytynyt lokien lähettämistä varten. Asenna sähköpostisovellus.</string>
|
||||
<string name="login">Kirjaudu sisään</string>
|
||||
|
@ -745,6 +746,7 @@ GNU yleinen lisenssi, versio 2</string>
|
|||
<string name="trashbin_file_not_restored">Tiedostoa %1$s ei voitu palauttaa!</string>
|
||||
<string name="trashbin_loading_failed">Roskakorin lataaminen epäonnistui!</string>
|
||||
<string name="trashbin_not_emptied">Tiedostoja ei voitu poistaa pysyvästi!</string>
|
||||
<string name="unlock_file">Vapauta tiedoston lukitus</string>
|
||||
<string name="unread_comments">Lukemattomia kommentteja on olemassa</string>
|
||||
<string name="unset_encrypted">Poista salaus</string>
|
||||
<string name="unset_favorite">Poista suosikeista</string>
|
||||
|
|
|
@ -400,6 +400,7 @@ Attention la suppression est irréversible.</string>
|
|||
<string name="local_file_not_found_message">Le fichier n\'a pas été trouvé sur le système de fichier local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Il n\'y a pas d\'autres dossiers.</string>
|
||||
<string name="lock_file">Verrouiller le fichier</string>
|
||||
<string name="log_send_mail_subject">Journaux de l\'application Android %1$s</string>
|
||||
<string name="log_send_no_mail_app">Pas d\'app d\'envoie de logs trouvé. Installer un client e-mail.</string>
|
||||
<string name="login">Se connecter</string>
|
||||
|
@ -753,6 +754,7 @@ Attention la suppression est irréversible.</string>
|
|||
<string name="trashbin_file_not_restored">Le fichier %1$s n\'a pas pu être restauré !</string>
|
||||
<string name="trashbin_loading_failed">Le chargement de la corbeille a échoué !</string>
|
||||
<string name="trashbin_not_emptied">Des fichiers n\'ont pas pu être supprimés de manière définitive !</string>
|
||||
<string name="unlock_file">Déverrouiller le fichier</string>
|
||||
<string name="unread_comments">Il y a des commentaire non lus</string>
|
||||
<string name="unset_encrypted">Désactiver le chiffrement</string>
|
||||
<string name="unset_favorite">Supprimer des favoris</string>
|
||||
|
|
|
@ -372,6 +372,7 @@
|
|||
<string name="local_file_not_found_message">Non se atopou o ficheiro no sistema local de ficheiros</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Xa non hai máis cartafoles</string>
|
||||
<string name="lock_file">Bloquear ficheiro</string>
|
||||
<string name="log_send_mail_subject">Atopáronse %1$s aplicacións de rexistros para Android</string>
|
||||
<string name="login">Acceder</string>
|
||||
<string name="login_url_helper_text">A ligazón á súa interface web %1$s cando a abre no navegador.</string>
|
||||
|
@ -700,6 +701,7 @@
|
|||
<string name="trashbin_file_not_deleted">Non foi posíbel eliminar o ficheiro %1$s!</string>
|
||||
<string name="trashbin_file_not_restored">Non foi posíbel restaurar o ficheiro %1$s!</string>
|
||||
<string name="trashbin_not_emptied">Non foi posíbel eliminar de xeito permanente o ficheiro!</string>
|
||||
<string name="unlock_file">Desbloquear ficheiro</string>
|
||||
<string name="unread_comments">Existen comentarios sen ler</string>
|
||||
<string name="unset_encrypted">Estabelecer como NON cifrado</string>
|
||||
<string name="unset_favorite">Retirar dos favoritos</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Datoteka nije pronađena u lokalnom datotečnom sustavu</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Nema drugih mapa.</string>
|
||||
<string name="lock_file">Zaključaj datoteku</string>
|
||||
<string name="log_send_mail_subject">Zapisnici aplikacija za Android %1$s</string>
|
||||
<string name="log_send_no_mail_app">Nije pronađena nijedna aplikacija za slanje zapisa. Instalirajte klijent e-pošte.</string>
|
||||
<string name="login">Prijava</string>
|
||||
|
@ -753,6 +754,7 @@
|
|||
<string name="trashbin_file_not_restored">Datoteku %1$s nije moguće vratiti!</string>
|
||||
<string name="trashbin_loading_failed">Učitavanje kante za smeće nije uspjelo!</string>
|
||||
<string name="trashbin_not_emptied">Datoteke nije moguće trajno izbrisati!</string>
|
||||
<string name="unlock_file">Otključaj datoteku</string>
|
||||
<string name="unread_comments">Postoje nepročitani komentari</string>
|
||||
<string name="unset_encrypted">Ukloni šifriranje</string>
|
||||
<string name="unset_favorite">Ukloni iz favorita</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">Hiba a fájlhoz hozzászóláskor</string>
|
||||
<string name="error_crash_title">A(z) %1$s összeomlott</string>
|
||||
<string name="error_creating_file_from_template">Hiba a fájl sablonból történő létrehozása során</string>
|
||||
<string name="error_file_lock">Hiba a fájl zárolási állapotának módosítása során</string>
|
||||
<string name="error_report_issue_action">Jelentés</string>
|
||||
<string name="error_report_issue_text">Jelenti a hibát a követőbe? (GitHub-fiók szükséges)</string>
|
||||
<string name="error_retrieving_file">Hiba a fájl lekérésekor</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">A fájl nem található a helyi fájlrendszeren</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Nincs több mappa.</string>
|
||||
<string name="lock_expiration_info">Lejárat: %1$s</string>
|
||||
<string name="lock_file">Fájl zárolása</string>
|
||||
<string name="locked_by">Zárolta: %1$s</string>
|
||||
<string name="locked_by_app">Zárolta: %1$s alkalmazás</string>
|
||||
<string name="log_send_mail_subject">%1$s androidos alkalmazás naplói</string>
|
||||
<string name="log_send_no_mail_app">Nincs alkalmazás a napló küldéshez. Telepítsen egy levelezőprogramot.</string>
|
||||
<string name="login">Bejelentkezés</string>
|
||||
|
@ -774,6 +779,7 @@ A Nextcloud itt érhető el: https://nextcloud.com</string>
|
|||
<string name="trashbin_file_not_restored">A(z) %1$s fájl nem állítható vissza!</string>
|
||||
<string name="trashbin_loading_failed">A kuka betöltése sikertelen.</string>
|
||||
<string name="trashbin_not_emptied">A fájlok nem törölhetők véglegesen!</string>
|
||||
<string name="unlock_file">Fájl feloldása</string>
|
||||
<string name="unread_comments">Olvasatlan hozzászólások vannak</string>
|
||||
<string name="unset_encrypted">Titkosítás kikapcsolása</string>
|
||||
<string name="unset_favorite">Eltávolítás a kedvencekből</string>
|
||||
|
|
|
@ -360,6 +360,7 @@
|
|||
<string name="local_file_not_found_message">Skrá fannst ekki á staðværu skráakerfi</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Það eru engar fleiri möppur.</string>
|
||||
<string name="lock_file">Læsa skrá</string>
|
||||
<string name="log_send_mail_subject">%1$s atvikaskrár Android-forrita</string>
|
||||
<string name="login">Skrá inn</string>
|
||||
<string name="logs_menu_delete">Eyða atvikaskrám</string>
|
||||
|
@ -675,6 +676,7 @@
|
|||
<string name="trashbin_file_not_deleted">Ekki tókst að eyða %1$s skránni!</string>
|
||||
<string name="trashbin_file_not_restored">Ekki tókst að endurheimta %1$s skrána!</string>
|
||||
<string name="trashbin_not_emptied">Ekki tókst að eyða skránum endanlega!</string>
|
||||
<string name="unlock_file">Aflæsa skrá</string>
|
||||
<string name="unread_comments">Ólesnar athugasemdir eru fyrirliggjandi</string>
|
||||
<string name="unset_encrypted">Gera dulritun óvirka</string>
|
||||
<string name="unset_favorite">Fjarlægja úr eftirlætislista</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">File non trovato nel file system locale</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Non ci sono ulteriori cartelle.</string>
|
||||
<string name="lock_file">Blocca file</string>
|
||||
<string name="log_send_mail_subject">Registri applicazione %1$s Android</string>
|
||||
<string name="log_send_no_mail_app">Non è stata trovata alcuna applicazione per inviare i log. Installa un client di posta elettronica.</string>
|
||||
<string name="login">Accedi</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">Il file %1$s non può essere ripristinato!</string>
|
||||
<string name="trashbin_loading_failed">Caricamento cestino non riuscito!</string>
|
||||
<string name="trashbin_not_emptied">I file non possono essere scaricati definitivamente!</string>
|
||||
<string name="unlock_file">Sblocca file</string>
|
||||
<string name="unread_comments">Sono presenti commenti non letti</string>
|
||||
<string name="unset_encrypted">Rimuovi cifratura</string>
|
||||
<string name="unset_favorite">Rimuovi dai preferiti</string>
|
||||
|
|
|
@ -354,6 +354,7 @@
|
|||
<string name="local_file_not_found_message">הקובץ לא נמצא במערכת הקבצים המקומית</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">אין תיקיות נוספות.</string>
|
||||
<string name="lock_file">נעילת קובץ</string>
|
||||
<string name="log_send_mail_subject">%1$s לוגים של יישום אנדרואיד</string>
|
||||
<string name="login">כניסה</string>
|
||||
<string name="logs_menu_delete">מחיקת יומנים</string>
|
||||
|
@ -681,6 +682,7 @@
|
|||
<string name="trashbin_file_not_deleted">לא ניתן למחוק את הקובץ %1$s!</string>
|
||||
<string name="trashbin_file_not_restored">לא ניתן לשחזר את הקובץ %1$s!</string>
|
||||
<string name="trashbin_not_emptied">לא ניתן למחוק קבצים לצמיתות!</string>
|
||||
<string name="unlock_file">שחרור קובץ</string>
|
||||
<string name="unread_comments">יש תגובות שלא נקראו</string>
|
||||
<string name="unset_encrypted">ביטול הגדרת ההצפנה</string>
|
||||
<string name="unset_favorite">הסרה מהמועדפים</string>
|
||||
|
|
|
@ -396,6 +396,7 @@
|
|||
<string name="local_file_not_found_message">ローカルファイルシステムにファイルが見つかりません</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">これ以上フォルダーがありません。</string>
|
||||
<string name="lock_file">ファイルをロック</string>
|
||||
<string name="log_send_mail_subject">%1$s アンドロイドアプリログ</string>
|
||||
<string name="log_send_no_mail_app">ログを送信するためのアプリが見つかりません。メールクライアントをインストールしてください。</string>
|
||||
<string name="login">ログイン</string>
|
||||
|
@ -746,6 +747,7 @@
|
|||
<string name="trashbin_file_not_restored">ファイル %1$s を復元できませんでした。</string>
|
||||
<string name="trashbin_loading_failed">ゴミ箱へのロードに失敗しました!</string>
|
||||
<string name="trashbin_not_emptied">ファイルを完全に削除できませんでした。</string>
|
||||
<string name="unlock_file">ファイルのロックを解除</string>
|
||||
<string name="unread_comments">未読のコメントが存在します</string>
|
||||
<string name="unset_encrypted">暗号化解除</string>
|
||||
<string name="unset_favorite">お気に入りから削除</string>
|
||||
|
|
|
@ -394,6 +394,7 @@
|
|||
<string name="local_file_not_found_message">내부 파일 시스템에서 파일을 찾을 수 없음</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">더 이상의 폴더가 없습니다.</string>
|
||||
<string name="lock_file">파일 잠금</string>
|
||||
<string name="log_send_mail_subject">%1$s Android 앱 로그</string>
|
||||
<string name="log_send_no_mail_app">로그 전송용 앱이 없습니다. 이메일 클라이언트를 설치하십시오.</string>
|
||||
<string name="login">로그인</string>
|
||||
|
@ -765,6 +766,7 @@ Nextcloud를 여기서 확인하십시오: https://nextcloud.com</string>
|
|||
<string name="trashbin_file_not_restored">%1$s 파일을 복구할 수 없습니다!</string>
|
||||
<string name="trashbin_loading_failed">휴지통 로딩 실패!</string>
|
||||
<string name="trashbin_not_emptied">파일을 영구적으로 삭제할 수 없습니다!</string>
|
||||
<string name="unlock_file">파일 잠금해제</string>
|
||||
<string name="unread_comments">읽지 않은 댓글 있음</string>
|
||||
<string name="unset_encrypted">암호화 해제</string>
|
||||
<string name="unset_favorite">즐겨찾기에서 제거</string>
|
||||
|
|
|
@ -388,6 +388,7 @@
|
|||
<string name="local_file_not_found_message">Failas nerastas vietinėje failų sistemoje</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Nėra kitų aplankų</string>
|
||||
<string name="lock_file">Užrakinti failą</string>
|
||||
<string name="log_send_mail_subject">%1$s Android žurnalai</string>
|
||||
<string name="login">Prisijungti</string>
|
||||
<string name="logs_menu_delete">Ištrinti žurnalus</string>
|
||||
|
@ -729,6 +730,7 @@
|
|||
<string name="trashbin_file_not_restored">Nepavyko atkurti failo %1$s!</string>
|
||||
<string name="trashbin_loading_failed">Nepavyko įkelti šiukšliadėžės!</string>
|
||||
<string name="trashbin_not_emptied">Nepavyko ištrinti failų visam laikui!</string>
|
||||
<string name="unlock_file">Atrakinti failą</string>
|
||||
<string name="unread_comments">Yra neskaitytų komentarų</string>
|
||||
<string name="unset_encrypted">Atjungti šifravimą</string>
|
||||
<string name="unset_favorite">Šalinti iš mėgstamų</string>
|
||||
|
|
|
@ -355,6 +355,7 @@
|
|||
<string name="local_file_not_found_message">Датотеката не е пронајдена во локалното складиште</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">.Нема повеќе папки</string>
|
||||
<string name="lock_file">Заклучи датотека</string>
|
||||
<string name="log_send_mail_subject">%1$s Апликација на Андроид за логови</string>
|
||||
<string name="login">Најава</string>
|
||||
<string name="logs_menu_delete">Избриши записи</string>
|
||||
|
@ -665,6 +666,7 @@
|
|||
<string name="trashbin_file_not_deleted">Датотеката %1$s неможе да се избрише!</string>
|
||||
<string name="trashbin_file_not_restored">Датотеката %1$s неможе да се врати!</string>
|
||||
<string name="trashbin_not_emptied">Датотеките неможат да бидат избрижани трајно!</string>
|
||||
<string name="unlock_file">Отклучи датотека</string>
|
||||
<string name="unread_comments">Постои непрочитан коментар</string>
|
||||
<string name="unset_encrypted">Отстрани енкрипција</string>
|
||||
<string name="unset_favorite">Отстрани од фаворити</string>
|
||||
|
|
|
@ -398,6 +398,7 @@
|
|||
<string name="local_file_not_found_message">Het bestand is niet te vinden binnen het lokale bestandssysteem.</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Er zijn niet meer mappen.</string>
|
||||
<string name="lock_file">Vergrendel bestand</string>
|
||||
<string name="log_send_mail_subject">%1$s-Android-app-logs</string>
|
||||
<string name="log_send_no_mail_app">Geen applicatie gevonden voor het versturen van de logs. Installeer een email client.</string>
|
||||
<string name="login">Inloggen</string>
|
||||
|
@ -751,6 +752,7 @@
|
|||
<string name="trashbin_file_not_restored">Bestand %1$s kon niet worden hersteld!</string>
|
||||
<string name="trashbin_loading_failed">Laden prullenbak mislukt!</string>
|
||||
<string name="trashbin_not_emptied">Bestanden konden niet permanent worden verwijderd!</string>
|
||||
<string name="unlock_file">Ontgrendel bestand</string>
|
||||
<string name="unread_comments">Er zijn ongelezen reacties</string>
|
||||
<string name="unset_encrypted">Niet ingestelde versleuteling</string>
|
||||
<string name="unset_favorite">Verwijderen uit favorieten</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Plik nie został znaleziony w lokalnym systemie plików</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Nie ma kolejnych katalogów.</string>
|
||||
<string name="lock_file">Zablokuj plik</string>
|
||||
<string name="log_send_mail_subject">%1$s logi aplikacji Android</string>
|
||||
<string name="log_send_no_mail_app">Brak aplikacji do wysyłania logów. Zainstaluj klienta poczty e-mail.</string>
|
||||
<string name="login">Zaloguj</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">Plik %1$s nie może zostać przywrócony!</string>
|
||||
<string name="trashbin_loading_failed">Wczytywanie kosza nie powiodło się!</string>
|
||||
<string name="trashbin_not_emptied">Pliki nie mogą być trwale usunięte!</string>
|
||||
<string name="unlock_file">Odblokuj plik</string>
|
||||
<string name="unread_comments">Nieprzeczytane komentarze</string>
|
||||
<string name="unset_encrypted">Wyłącz szyfrowanie</string>
|
||||
<string name="unset_favorite">Usuń z ulubionych</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Arquivo não encontrado no sistema de arquivos local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Não há outras pastas.</string>
|
||||
<string name="lock_file">Travar arquivo</string>
|
||||
<string name="log_send_mail_subject">%1$s logs do aplicativo Android</string>
|
||||
<string name="log_send_no_mail_app">Nenhum aplicativo para envio de registros foi encontrado. Instale um cliente de e-mail.</string>
|
||||
<string name="login">Entrar</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">Arquivo %1$s não pôde ser restaurado!</string>
|
||||
<string name="trashbin_loading_failed">Falha ao carregar a lixeira! </string>
|
||||
<string name="trashbin_not_emptied">Os arquivos não puderam ser excluídos permanentemente!</string>
|
||||
<string name="unlock_file">Destravar arquivo</string>
|
||||
<string name="unread_comments">Existem comentários não lidos</string>
|
||||
<string name="unset_encrypted">Definir como não criptografado</string>
|
||||
<string name="unset_favorite">Remover dos favoritos</string>
|
||||
|
|
|
@ -387,6 +387,7 @@
|
|||
<string name="local_file_not_found_message">Ficheiros não encontrados no sistema de ficheiros local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Não existem mais pastas.</string>
|
||||
<string name="lock_file">Bloquear ficheiro </string>
|
||||
<string name="log_send_mail_subject">%1$s registos de aplicação Android</string>
|
||||
<string name="log_send_no_mail_app">Não encontro aplicação para o envio de logs. Por favor Instale um cliente de email.</string>
|
||||
<string name="login">Iniciar Sessão</string>
|
||||
|
@ -730,6 +731,7 @@ Aproveite o novo e melhorado envio automático.</string>
|
|||
<string name="trashbin_file_not_restored">Ficheiro %1$s não pôde ser restaurado!</string>
|
||||
<string name="trashbin_loading_failed">Impossível ler a pasta da reciclagem!</string>
|
||||
<string name="trashbin_not_emptied">Os ficheiros não puderam ser permanentemente apagados!</string>
|
||||
<string name="unlock_file">Desbloquear ficheiro</string>
|
||||
<string name="unread_comments">Existem comentários não lidos</string>
|
||||
<string name="unset_encrypted">Encriptação não definida</string>
|
||||
<string name="unset_favorite">Remover dos favoritos</string>
|
||||
|
|
|
@ -397,6 +397,7 @@
|
|||
<string name="local_file_not_found_message">Fișierul nu a fost găsit în sistemul local</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s </string>
|
||||
<string name="local_folder_list_empty">Nu există dosare.</string>
|
||||
<string name="lock_file">Blochează fișierul</string>
|
||||
<string name="log_send_mail_subject">%1$s înregistrările app-ului Android</string>
|
||||
<string name="log_send_no_mail_app">Nu există nici o aplicație pentru a trimite fisiere log. Vă rugăm instalați un client de email.</string>
|
||||
<string name="login">Autentificare</string>
|
||||
|
@ -749,6 +750,7 @@
|
|||
<string name="trashbin_file_not_restored">Fișierul %1$s nu a putut fi restaurat!</string>
|
||||
<string name="trashbin_loading_failed">Încărcarea coșului de gunoi a eșuat!</string>
|
||||
<string name="trashbin_not_emptied">Fișierele nu au putut fi șterse permanent!</string>
|
||||
<string name="unlock_file">Deblochează fișierul</string>
|
||||
<string name="unread_comments">Există comentarii necitite</string>
|
||||
<string name="unset_encrypted">Dezactivați criptarea</string>
|
||||
<string name="unset_favorite">Ștergeți din favorite</string>
|
||||
|
|
|
@ -402,6 +402,7 @@
|
|||
<string name="local_file_not_found_message">Файл не найден в локальной файловой системе</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Нет других каталогов.</string>
|
||||
<string name="lock_file">Заблокировать файл</string>
|
||||
<string name="log_send_mail_subject">Журналы приложения %1$s для Android</string>
|
||||
<string name="log_send_no_mail_app">Приложение для отправки журналов не найдено. Пожалуйста, установите почтовый клиент.</string>
|
||||
<string name="login">Войти</string>
|
||||
|
@ -757,6 +758,7 @@
|
|||
<string name="trashbin_file_not_restored">Файл «%1$s» не может быть восстановлен!</string>
|
||||
<string name="trashbin_loading_failed">Загрузка корзины не удалась!</string>
|
||||
<string name="trashbin_not_emptied">Файлы не могут быть удалены окончательно!</string>
|
||||
<string name="unlock_file">Разблокировать файл</string>
|
||||
<string name="unread_comments">Имеются непрочитанные комментарии</string>
|
||||
<string name="unset_encrypted">Расшифровать</string>
|
||||
<string name="unset_favorite">Убрать из избранного</string>
|
||||
|
|
|
@ -377,6 +377,7 @@
|
|||
<string name="local_file_not_found_message">Documentu no agatadu in su sistema de documentos locale</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Non ddoe sunt àteras cartellas.</string>
|
||||
<string name="lock_file">Bloca su documentu</string>
|
||||
<string name="log_send_mail_subject">%1$s registros de s\'aplicatzione Android</string>
|
||||
<string name="log_send_no_mail_app">No est è istada agatada peruna aplicatzione pro imbiare is log. Installa unu cliente de posta eletrònica.</string>
|
||||
<string name="login">Intra</string>
|
||||
|
@ -711,6 +712,7 @@
|
|||
<string name="trashbin_file_not_restored">No at fatu a recuperare s\'archìviu %1$s!</string>
|
||||
<string name="trashbin_loading_failed">Carrigamentu de s\'àliga faddidu!</string>
|
||||
<string name="trashbin_not_emptied">No at fatu a cantzellare is archìvios in manera permanente!</string>
|
||||
<string name="unlock_file">Isbloca su documentu</string>
|
||||
<string name="unread_comments">Ddoe sunt cummentos non lèghidos</string>
|
||||
<string name="unset_encrypted">Tzifradura non cunfigurada</string>
|
||||
<string name="unset_favorite">Boga·nche·ddu dae is preferidos</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Súbor nebolo možné nájsť na lokálnom úložisku</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Neexistujú ďalšie priečinky.</string>
|
||||
<string name="lock_file">Zamknúť súbor</string>
|
||||
<string name="log_send_mail_subject">%1$s Android app logs</string>
|
||||
<string name="log_send_no_mail_app">Aplikácia na odoslanie logov nenájdená. Prosím nainštalujte emailovú aplikáciu.</string>
|
||||
<string name="login">Prihlásiť sa</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">Súbor %1$s sa nedá obnoviť!</string>
|
||||
<string name="trashbin_loading_failed">Načítanie obsahu koša sa nepodarilo!</string>
|
||||
<string name="trashbin_not_emptied">Nepodarilo sa trvalo vymazať súbory!</string>
|
||||
<string name="unlock_file">Odomknúť súbor</string>
|
||||
<string name="unread_comments">Existujú neprečítané komentáre</string>
|
||||
<string name="unset_encrypted">Vypnúť šifrovanie</string>
|
||||
<string name="unset_favorite">Odstrániť z obľúbených</string>
|
||||
|
|
|
@ -391,6 +391,7 @@
|
|||
<string name="local_file_not_found_message">Na krajevnem sistemu datoteke ni mogoče najti</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Ni drugih map.</string>
|
||||
<string name="lock_file">Zakleni datoteko</string>
|
||||
<string name="log_send_mail_subject">%1$s dnevniki programa</string>
|
||||
<string name="log_send_no_mail_app">Ni nameščenega programa za pošiljanje dnevnikov. Namestiti je treba program za elektronsko pošto.</string>
|
||||
<string name="login">Prijava</string>
|
||||
|
@ -737,6 +738,7 @@
|
|||
<string name="trashbin_file_not_restored">Datoteke %1$s ni mogoče obnoviti!</string>
|
||||
<string name="trashbin_loading_failed">Nalaganje smeti je spodletelo!</string>
|
||||
<string name="trashbin_not_emptied">Datotek ni mogoče trajno izbrisati!</string>
|
||||
<string name="unlock_file">Odkleni datoteko</string>
|
||||
<string name="unread_comments">Obstajajo so neprebrane opombe</string>
|
||||
<string name="unset_encrypted">Odstrani šifriranje</string>
|
||||
<string name="unset_favorite">Odstrani iz priljubljenih</string>
|
||||
|
|
|
@ -357,6 +357,7 @@
|
|||
<string name="local_file_not_found_message">Фајл није нађен у локалном фајл-систему</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Нема више фасцикли</string>
|
||||
<string name="lock_file">Закључај фајл</string>
|
||||
<string name="log_send_mail_subject">Записници %1$s Андроид апликације</string>
|
||||
<string name="login">Пријава</string>
|
||||
<string name="logs_menu_delete">Обриши записнике</string>
|
||||
|
@ -671,6 +672,7 @@
|
|||
<string name="trashbin_file_not_deleted">Фајл %1$s не може да се обрише!</string>
|
||||
<string name="trashbin_file_not_restored">Фајл %1$s не може да се поврати!</string>
|
||||
<string name="trashbin_not_emptied">Фајл не може да се обрише неповратно!</string>
|
||||
<string name="unlock_file">Откључај фајл</string>
|
||||
<string name="unread_comments">Постоје непрочитани коментари</string>
|
||||
<string name="unset_encrypted">Искључи шифровање</string>
|
||||
<string name="unset_favorite">Уклони из омиљених</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Filen hittades inte i det lokala filsystemet</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Det finna inga fler mappar.</string>
|
||||
<string name="lock_file">Lås fil</string>
|
||||
<string name="log_send_mail_subject">%1$s Android-apploggar</string>
|
||||
<string name="log_send_no_mail_app">Ingen app för att skicka loggar hittades. Vänligen installera en e-postklient.</string>
|
||||
<string name="login">Logga in</string>
|
||||
|
@ -757,6 +758,7 @@
|
|||
<string name="trashbin_file_not_restored">Fil %1$s kunde inte återställas!</string>
|
||||
<string name="trashbin_loading_failed">Laddning av papperskorg misslyckades!</string>
|
||||
<string name="trashbin_not_emptied">Filer kunde inte tas bort permanent!</string>
|
||||
<string name="unlock_file">Lås upp fil</string>
|
||||
<string name="unread_comments">Olästa kommentarer finns</string>
|
||||
<string name="unset_encrypted">Ta bort som krypterad</string>
|
||||
<string name="unset_favorite">Ta bort från favoriter</string>
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<string name="local_file_not_found_message">Dosya yerel dosya sisteminde bulunamadı</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Bu klasörde başka bir klasör yok.</string>
|
||||
<string name="lock_file">Dosyayı kilitle</string>
|
||||
<string name="log_send_mail_subject">%1$s Android uygulaması günlükleri</string>
|
||||
<string name="log_send_no_mail_app">Günlüklerin gönderilebileceği bir uygulama bulunamadı. Lütfen bir e-posta uygulaması kurun.</string>
|
||||
<string name="login">Oturum aç</string>
|
||||
|
@ -756,6 +757,7 @@
|
|||
<string name="trashbin_file_not_restored">%1$s dosyası geri yüklenemedi!</string>
|
||||
<string name="trashbin_loading_failed">Çöp kutusu yüklenemedi!</string>
|
||||
<string name="trashbin_not_emptied">Dosyalar kalıcı olarak silinemedi!</string>
|
||||
<string name="unlock_file">Dosya kilidini aç</string>
|
||||
<string name="unread_comments">Okunmamış yorumlar var</string>
|
||||
<string name="unset_encrypted">Şifrelemeyi kaldır</string>
|
||||
<string name="unset_favorite">Sık kullanılanlardan kaldır</string>
|
||||
|
|
|
@ -382,6 +382,7 @@
|
|||
<string name="local_file_not_found_message">Файл не знайдено у локальній файловій системі</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">Тут відсутні інші каталоги.</string>
|
||||
<string name="lock_file">Заблокувати файл</string>
|
||||
<string name="log_send_mail_subject">%1$s Android лог додатку</string>
|
||||
<string name="log_send_no_mail_app">Не знайдено застосунку для надсилання журналу. Будь ласка, встановіть поштовий клієнт.</string>
|
||||
<string name="login">Увійти</string>
|
||||
|
@ -717,6 +718,7 @@
|
|||
<string name="trashbin_file_not_restored">Файл %1$s неможливо відновити!</string>
|
||||
<string name="trashbin_loading_failed">Неможливо відкрити кошик!</string>
|
||||
<string name="trashbin_not_emptied">Неможливо вилучити файли!</string>
|
||||
<string name="unlock_file">Розблокувати файл</string>
|
||||
<string name="unread_comments">Доступні непрочитані коментарі</string>
|
||||
<string name="unset_encrypted">Зняти шифрування</string>
|
||||
<string name="unset_favorite">Вилучити з улюблених</string>
|
||||
|
|
|
@ -397,6 +397,7 @@
|
|||
<string name="local_file_not_found_message">本地文件系统无法找到此文件</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">没有其他文件夹。</string>
|
||||
<string name="lock_file">锁定文件</string>
|
||||
<string name="log_send_mail_subject">%1$s 安卓应用日志</string>
|
||||
<string name="log_send_no_mail_app">没有找到发送日志文件的应用程序。请安装电子邮件客户端。</string>
|
||||
<string name="login">登录</string>
|
||||
|
@ -752,6 +753,7 @@
|
|||
<string name="trashbin_file_not_restored">文件 %1$s 无法被恢复!</string>
|
||||
<string name="trashbin_loading_failed">加载垃圾箱失败!</string>
|
||||
<string name="trashbin_not_emptied">文件无法永久删除!</string>
|
||||
<string name="unlock_file">解锁文件</string>
|
||||
<string name="unread_comments">有未读评论</string>
|
||||
<string name="unset_encrypted">不设置加密</string>
|
||||
<string name="unset_favorite">从收藏列表移除</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">留言錯誤</string>
|
||||
<string name="error_crash_title">%1$s失敗</string>
|
||||
<string name="error_creating_file_from_template">從模板創建檔案時出錯</string>
|
||||
<string name="error_file_lock">更改檔案上鎖狀態時出錯</string>
|
||||
<string name="error_report_issue_action">舉報</string>
|
||||
<string name="error_report_issue_text">想舉報問題?(需要GitHub賬號)</string>
|
||||
<string name="error_retrieving_file">檢索檔案時發生錯誤</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">近端檔案系統中找不到檔案</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">沒有其他資料夾了</string>
|
||||
<string name="lock_expiration_info">過期:%1$s</string>
|
||||
<string name="lock_file">上鎖檔案</string>
|
||||
<string name="locked_by">被 %1$s 鎖上</string>
|
||||
<string name="locked_by_app">被 %1$s 應用程式鎖上</string>
|
||||
<string name="log_send_mail_subject">%1$s Android 應用程式記錄</string>
|
||||
<string name="log_send_no_mail_app">找不到用於發送記錄的應用程式。請安裝電子郵件客戶端。</string>
|
||||
<string name="login">登入</string>
|
||||
|
@ -756,6 +761,7 @@
|
|||
<string name="trashbin_file_not_restored">檔案 %1$s 不能被還原!</string>
|
||||
<string name="trashbin_loading_failed">載入回收桶失敗!</string>
|
||||
<string name="trashbin_not_emptied">無法永久刪除文件!</string>
|
||||
<string name="unlock_file">解鎖檔案</string>
|
||||
<string name="unread_comments">有未讀留言</string>
|
||||
<string name="unset_encrypted">取消加密</string>
|
||||
<string name="unset_favorite">從最愛中移除</string>
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
<string name="error_comment_file">留言錯誤</string>
|
||||
<string name="error_crash_title">%1$s失敗</string>
|
||||
<string name="error_creating_file_from_template">從範本建立檔案時發生錯誤</string>
|
||||
<string name="error_file_lock">變更檔案鎖定狀態時發生錯誤</string>
|
||||
<string name="error_report_issue_action">回報</string>
|
||||
<string name="error_report_issue_text">要回報議題至追蹤程式?(需要 GitHub 帳號)</string>
|
||||
<string name="error_retrieving_file">擷取檔案時發生錯誤</string>
|
||||
|
@ -401,6 +402,10 @@
|
|||
<string name="local_file_not_found_message">本機檔案系統中找不到檔案</string>
|
||||
<string name="local_folder_friendly_path">%1$s/%2$s</string>
|
||||
<string name="local_folder_list_empty">沒有其他資料夾了</string>
|
||||
<string name="lock_expiration_info">過期:%1$s</string>
|
||||
<string name="lock_file">上鎖檔案</string>
|
||||
<string name="locked_by">被 %1$s 鎖定</string>
|
||||
<string name="locked_by_app">被 %1$s 應用程式鎖定</string>
|
||||
<string name="log_send_mail_subject">%1$s Android 應用程式記錄</string>
|
||||
<string name="log_send_no_mail_app">無應用程式送出的紀錄。請安裝電子郵件客戶端。</string>
|
||||
<string name="login">登入</string>
|
||||
|
@ -756,6 +761,7 @@
|
|||
<string name="trashbin_file_not_restored">檔案 %1$s 不能被還原!</string>
|
||||
<string name="trashbin_loading_failed">載入回收桶失敗!</string>
|
||||
<string name="trashbin_not_emptied">無法永久刪除檔案!</string>
|
||||
<string name="unlock_file">解鎖檔案</string>
|
||||
<string name="unread_comments">有未讀留言</string>
|
||||
<string name="unset_encrypted">取消加密</string>
|
||||
<string name="unset_favorite">從最愛中移除</string>
|
||||
|
|
|
@ -1016,4 +1016,10 @@
|
|||
<string name="select_media_folder">Set media folder</string>
|
||||
<string name="choose_location">Choose location</string>
|
||||
<string name="common_select">Select</string>
|
||||
<string name="lock_file">Lock file</string>
|
||||
<string name="unlock_file">Unlock file</string>
|
||||
<string name="error_file_lock">Error changing file lock status</string>
|
||||
<string name="locked_by">Locked by %1$s</string>
|
||||
<string name="locked_by_app">Locked by %1$s app</string>
|
||||
<string name="lock_expiration_info">Expires: %1$s</string>
|
||||
</resources>
|
||||
|
|
|
@ -386,6 +386,14 @@
|
|||
<item name="android:textColorPrimary">@color/text_color</item>
|
||||
</style>
|
||||
|
||||
<style name="Nextcloud.Widget.PopupMenu" parent="@style/Widget.AppCompat.PopupMenu">
|
||||
<item name="android:textColor">@color/menu_item_text_color</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.ToolbarWithDisabled" parent="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
||||
<item name="android:textColor">@color/menu_item_text_color</item>
|
||||
</style>
|
||||
|
||||
<style name="MaterialListItemSingleLine">
|
||||
<item name="android:clickable">true</item>
|
||||
<item name="android:background">?android:selectableItemBackground</item>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Álvaro Brey Vilas
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.android.files
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.lib.resources.files.model.FileLockType
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FileLockingHelperTest {
|
||||
|
||||
@Test
|
||||
fun fileNotLocked_cannotUnlock() {
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = false
|
||||
lockOwnerId = USER_NAME
|
||||
lockType = FileLockType.MANUAL
|
||||
}
|
||||
Assert.assertFalse(FileLockingHelper.canUserUnlockFile(USER_NAME, file))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ownerNotUser_cannotUnlock() {
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = true
|
||||
lockOwnerId = "bloop"
|
||||
lockType = FileLockType.MANUAL
|
||||
}
|
||||
Assert.assertFalse(FileLockingHelper.canUserUnlockFile(USER_NAME, file))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun typeNotManual_cannotUnlock() {
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = true
|
||||
lockOwnerId = USER_NAME
|
||||
lockType = FileLockType.COLLABORATIVE
|
||||
}
|
||||
Assert.assertFalse(FileLockingHelper.canUserUnlockFile(USER_NAME, file))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canUnlock() {
|
||||
val file = OCFile("/foo.md").apply {
|
||||
isLocked = true
|
||||
lockOwnerId = USER_NAME
|
||||
lockType = FileLockType.MANUAL
|
||||
}
|
||||
Assert.assertTrue(FileLockingHelper.canUserUnlockFile(USER_NAME, file))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val USER_NAME = "user"
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ buildscript {
|
|||
mockitoKotlinVersion = "4.0.0"
|
||||
mockkVersion = "1.12.3"
|
||||
powermockVersion = "2.0.9"
|
||||
byteBuddyVersion = "1.12.9"
|
||||
byteBuddyVersion = "1.12.10"
|
||||
espressoVersion = "3.4.0"
|
||||
workRuntime = "2.7.1"
|
||||
fidoVersion = "4.1.0"
|
||||
|
@ -26,17 +26,15 @@ buildscript {
|
|||
subprojects {
|
||||
buildscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
maven {
|
||||
url 'https://plugins.gradle.org/m2/'
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
maven { url "https://jitpack.io" }
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DO NOT TOUCH; GENERATED BY DRONE
|
||||
<span class="mdl-layout-title">Lint Report: 88 warnings</span>
|
||||
<span class="mdl-layout-title">Lint Report: 87 warnings</span>
|
||||
|
|
Loading…
Reference in a new issue