Merge master

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2023-10-16 16:32:13 +02:00
commit 8a60b0e0f1
No known key found for this signature in database
GPG key ID: 4E577DC593B59BDF
30 changed files with 135 additions and 118 deletions

View file

@ -21,7 +21,7 @@ jobs:
steps: steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: set up JDK 17 - name: set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 17 java-version: 17

View file

@ -21,7 +21,7 @@ jobs:
steps: steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 17 java-version: 17

View file

@ -32,7 +32,7 @@ jobs:
with: with:
swap-size-gb: 10 swap-size-gb: 10
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Set up JDK 17 - name: Set up JDK 17
@ -46,4 +46,4 @@ jobs:
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
./gradlew assembleDebug ./gradlew assembleDebug
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3

View file

@ -18,7 +18,7 @@ jobs:
steps: steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 17 java-version: 17

View file

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }} if: ${{ steps.check-secrets.outputs.ok == 'true' }}
- name: set up JDK 17 - name: set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }} if: ${{ steps.check-secrets.outputs.ok == 'true' }}
with: with:
distribution: "temurin" distribution: "temurin"

View file

@ -37,6 +37,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard. # Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2 uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View file

@ -40,7 +40,7 @@ jobs:
~/.android/adb* ~/.android/adb*
key: avd-${{ matrix.api-level }} key: avd-${{ matrix.api-level }}
- uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 - uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 17 java-version: 17

View file

@ -20,7 +20,7 @@ jobs:
steps: steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 17 java-version: 17

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -314,7 +314,7 @@ public abstract class AbstractIT {
return currentActivity; return currentActivity;
} }
protected void shortSleep() { protected static void shortSleep() {
try { try {
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException e) { } catch (InterruptedException e) {

View file

@ -135,10 +135,20 @@ public abstract class AbstractOnServerIT extends AbstractIT {
.isSuccess()); .isSuccess());
} }
assertTrue(new RemoveFileRemoteOperation(remoteFile.getRemotePath()) boolean removeResult = false;
for (int i = 0; i < 5; i++) {
removeResult = new RemoveFileRemoteOperation(remoteFile.getRemotePath())
.execute(client) .execute(client)
.isSuccess() .isSuccess();
);
if (removeResult) {
break;
}
shortSleep();
}
assertTrue(removeResult);
} }
} }
} }

View file

@ -41,7 +41,6 @@ import com.owncloud.android.operations.RemoveFileOperation;
import com.owncloud.android.operations.UploadFileOperation; import com.owncloud.android.operations.UploadFileOperation;
import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.FileStorageUtils;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -106,29 +105,6 @@ public class UploadIT extends AbstractOnServerIT {
createDummyFiles(); createDummyFiles();
} }
@After
public void after() {
RemoteOperationResult result = new RefreshFolderOperation(getStorageManager().getFileByPath("/"),
System.currentTimeMillis() / 1000L,
false,
true,
getStorageManager(),
user,
targetContext)
.execute(client);
// cleanup only if folder exists
if (result.isSuccess() && getStorageManager().getFileByDecryptedRemotePath(FOLDER) != null) {
new RemoveFileOperation(getStorageManager().getFileByDecryptedRemotePath(FOLDER),
false,
user,
false,
targetContext,
getStorageManager())
.execute(client);
}
}
@Test @Test
public void testEmptyUpload() { public void testEmptyUpload() {
OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/empty.txt", OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/empty.txt",
@ -529,8 +505,8 @@ public class UploadIT extends AbstractOnServerIT {
assertNotNull(ocFile); assertNotNull(ocFile);
assertEquals(remotePath, ocFile.getRemotePath()); assertEquals(remotePath, ocFile.getRemotePath());
assertEquals(new ImageDimension(451f, 529f), ocFile.getImageDimension()); assertEquals(new ImageDimension(300f, 200f), ocFile.getImageDimension());
assertEquals(new GeoLocation(49.99679166666667, 8.67198611111111), ocFile.getGeoLocation()); assertEquals(new GeoLocation(64, -46), ocFile.getGeoLocation());
} }
private void verifyStoragePath(OCFile file) { private void verifyStoragePath(OCFile file) {

View file

@ -20,6 +20,7 @@
*/ */
package com.owncloud.android.ui package com.owncloud.android.ui
import android.os.Build
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
@ -28,6 +29,7 @@ import androidx.test.espresso.web.sugar.Web
import androidx.test.espresso.web.webdriver.DriverAtoms import androidx.test.espresso.web.webdriver.DriverAtoms
import androidx.test.espresso.web.webdriver.Locator import androidx.test.espresso.web.webdriver.Locator
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.account.UserAccountManagerImpl import com.nextcloud.client.account.UserAccountManagerImpl
@ -59,6 +61,12 @@ class LoginIT : AbstractIT() {
@Test @Test
@Throws(InterruptedException::class) @Throws(InterruptedException::class)
@Suppress("MagicNumber", "SwallowedException") @Suppress("MagicNumber", "SwallowedException")
/**
* The CI/CD pipeline is encountering issues related to the Android version for this functionality.
* Therefore the test will only be executed on Android versions 10 and above.
*/
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
fun login() { fun login() {
val arguments = InstrumentationRegistry.getArguments() val arguments = InstrumentationRegistry.getArguments()
val baseUrl = arguments.getString("TEST_SERVER_URL")!! val baseUrl = arguments.getString("TEST_SERVER_URL")!!

View file

@ -26,6 +26,7 @@ package com.nextcloud.client.preferences;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.nextcloud.appReview.AppReviewShownModel; import com.nextcloud.appReview.AppReviewShownModel;
@ -437,7 +438,14 @@ public final class AppPreferencesImpl implements AppPreferences {
@Override @Override
public boolean isDarkModeEnabled() { public boolean isDarkModeEnabled() {
return getDarkThemeMode() == DarkMode.DARK; DarkMode mode = getDarkThemeMode();
if (mode == DarkMode.SYSTEM) {
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
}
return mode == DarkMode.DARK;
} }
@Override @Override

View file

@ -138,7 +138,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
keyboardUtils.showKeyboardForEditText(binding.filename); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.filename);
} }
@NonNull @NonNull

View file

@ -119,7 +119,7 @@ class ChooseTemplateDialogFragment : DialogFragment(), View.OnClickListener, Tem
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
keyboardUtils.showKeyboardForEditText(binding.filename) keyboardUtils.showKeyboardForEditText(dialog?.window, binding.filename)
} }
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

View file

@ -116,7 +116,7 @@ public class CreateFolderDialogFragment
super.onResume(); super.onResume();
bindButton(); bindButton();
keyboardUtils.showKeyboardForEditText(binding.userInput); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
} }
@NonNull @NonNull

View file

@ -90,7 +90,7 @@ public class NoteDialogFragment extends DialogFragment implements DialogInterfac
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
keyboardUtils.showKeyboardForEditText(binding.noteText); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.noteText);
} }
@NonNull @NonNull

View file

@ -34,8 +34,8 @@ import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.Button;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.nextcloud.client.di.Injectable; import com.nextcloud.client.di.Injectable;
@ -65,7 +65,7 @@ import androidx.fragment.app.DialogFragment;
* Triggers the rename operation when name is confirmed. * Triggers the rename operation when name is confirmed.
*/ */
public class RenameFileDialogFragment public class RenameFileDialogFragment
extends DialogFragment implements DialogInterface.OnClickListener, Injectable { extends DialogFragment implements DialogInterface.OnClickListener, TextWatcher, Injectable {
private static final String ARG_TARGET_FILE = "TARGET_FILE"; private static final String ARG_TARGET_FILE = "TARGET_FILE";
private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER"; private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER";
@ -76,8 +76,8 @@ public class RenameFileDialogFragment
private EditBoxDialogBinding binding; private EditBoxDialogBinding binding;
private OCFile mTargetFile; private OCFile mTargetFile;
private Button positiveButton; private MaterialButton positiveButton;
private Set<String> fileNames;
/** /**
* Public factory method to create new RenameFileDialogFragment instances. * Public factory method to create new RenameFileDialogFragment instances.
@ -97,20 +97,13 @@ public class RenameFileDialogFragment
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
initAlertDialog();
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.platform.colorTextButtons(positiveButton,
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
}
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
keyboardUtils.showKeyboardForEditText(binding.userInput); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
} }
@NonNull @NonNull
@ -133,62 +126,46 @@ public class RenameFileDialogFragment
OCFile parentFolder = requireArguments().getParcelable(ARG_PARENT_FOLDER); OCFile parentFolder = requireArguments().getParcelable(ARG_PARENT_FOLDER);
List<OCFile> folderContent = fileDataStorageManager.getFolderContent(parentFolder, false); List<OCFile> folderContent = fileDataStorageManager.getFolderContent(parentFolder, false);
Set<String> fileNames = Sets.newHashSetWithExpectedSize(folderContent.size()); fileNames = Sets.newHashSetWithExpectedSize(folderContent.size());
for (OCFile file : folderContent) { for (OCFile file : folderContent) {
fileNames.add(file.getFileName()); fileNames.add(file.getFileName());
} }
// Add TextChangedListener to handle showing/hiding the input warning message // Add TextChangedListener to handle showing/hiding the input warning message
binding.userInput.addTextChangedListener(new TextWatcher() { binding.userInput.addTextChangedListener(this);
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/**
* When user enters a hidden file name, the 'hidden file' message is shown.
* Otherwise, the message is ensured to be hidden.
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String newFileName = "";
if (binding.userInput.getText() != null) {
newFileName = binding.userInput.getText().toString().trim();
}
if (!TextUtils.isEmpty(newFileName) && newFileName.charAt(0) == '.') {
binding.userInputContainer.setError(getText(R.string.hidden_file_name_warning));
} else if (TextUtils.isEmpty(newFileName)) {
binding.userInputContainer.setError(getString(R.string.filename_empty));
positiveButton.setEnabled(false);
} else if (fileNames.contains(newFileName)) {
binding.userInputContainer.setError(getText(R.string.file_already_exists));
positiveButton.setEnabled(false);
} else if (binding.userInputContainer.getError() != null) {
binding.userInputContainer.setError(null);
// Called to remove extra padding
binding.userInputContainer.setErrorEnabled(false);
positiveButton.setEnabled(true);
}
}
});
// Build the dialog // Build the dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity()); MaterialAlertDialogBuilder builder = buildMaterialAlertDialog(view);
builder.setView(view)
.setPositiveButton(R.string.file_rename, this)
.setNeutralButton(R.string.common_cancel, this)
.setTitle(R.string.rename_dialog_title);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInputContainer.getContext(), builder); viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInputContainer.getContext(), builder);
return builder.create(); return builder.create();
} }
private MaterialAlertDialogBuilder buildMaterialAlertDialog(View view) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
builder
.setView(view)
.setPositiveButton(R.string.file_rename, this)
.setNegativeButton(R.string.common_cancel, this)
.setTitle(R.string.rename_dialog_title);
return builder;
}
private void initAlertDialog() {
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
}
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
@ -219,4 +196,41 @@ public class RenameFileDialogFragment
super.onDestroyView(); super.onDestroyView();
binding = null; binding = null;
} }
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/**
* When user enters a hidden file name, the 'hidden file' message is shown.
* Otherwise, the message is ensured to be hidden.
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String newFileName = "";
if (binding.userInput.getText() != null) {
newFileName = binding.userInput.getText().toString().trim();
}
if (!TextUtils.isEmpty(newFileName) && newFileName.charAt(0) == '.') {
binding.userInputContainer.setError(getText(R.string.hidden_file_name_warning));
} else if (TextUtils.isEmpty(newFileName)) {
binding.userInputContainer.setError(getString(R.string.filename_empty));
positiveButton.setEnabled(false);
} else if (fileNames.contains(newFileName)) {
binding.userInputContainer.setError(getText(R.string.file_already_exists));
positiveButton.setEnabled(false);
} else if (binding.userInputContainer.getError() != null) {
binding.userInputContainer.setError(null);
// Called to remove extra padding
binding.userInputContainer.setErrorEnabled(false);
positiveButton.setEnabled(true);
}
}
@Override
public void afterTextChanged(Editable s) {
}
} }

View file

@ -83,7 +83,7 @@ public class RenamePublicShareDialogFragment
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
keyboardUtils.showKeyboardForEditText(binding.userInput); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
} }
@NonNull @NonNull

View file

@ -99,7 +99,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
keyboardUtils.showKeyboardForEditText(binding.sharePassword); keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.sharePassword);
} }
/** /**

View file

@ -1,7 +1,9 @@
/* /*
* Nextcloud Android client application * Nextcloud Android client application
* *
* @author ZetaTom
* @author Álvaro Brey * @author Álvaro Brey
* Copyright (C) 2023 ZetaTom
* Copyright (C) 2022 Álvaro Brey * Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH * Copyright (C) 2022 Nextcloud GmbH
* *
@ -22,26 +24,18 @@
package com.owncloud.android.utils package com.owncloud.android.utils
import android.content.Context import android.view.Window
import android.view.inputmethod.InputMethodManager
import android.widget.EditText import android.widget.EditText
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import javax.inject.Inject import javax.inject.Inject
class KeyboardUtils @Inject constructor() { class KeyboardUtils @Inject constructor() {
fun showKeyboardForEditText(editText: EditText) { fun showKeyboardForEditText(window: Window?, editText: EditText) {
if (window != null) {
editText.requestFocus() editText.requestFocus()
// needs 100ms delay to account for focus animations WindowCompat.getInsetsController(window, editText).show(WindowInsetsCompat.Type.ime())
editText.postDelayed({ }
val context = editText.context
if (context != null) {
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
}
}, SHOW_INPUT_DELAY_MILLIS)
}
companion object {
private const val SHOW_INPUT_DELAY_MILLIS = 100L
} }
} }

View file

@ -843,6 +843,7 @@
<string name="trashbin_empty_message">ستتمكن من استعادة الملفات المحذوفة من هنا.</string> <string name="trashbin_empty_message">ستتمكن من استعادة الملفات المحذوفة من هنا.</string>
<string name="trashbin_file_not_deleted">الملف %1$s لا يمكن حذفه!</string> <string name="trashbin_file_not_deleted">الملف %1$s لا يمكن حذفه!</string>
<string name="trashbin_file_not_restored">الملف %1$s لا يمكن إسترجاعه!</string> <string name="trashbin_file_not_restored">الملف %1$s لا يمكن إسترجاعه!</string>
<string name="trashbin_file_remove">حذف نهائي</string>
<string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string> <string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string>
<string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string> <string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string>
<string name="unlock_file">فتح قفل الملف</string> <string name="unlock_file">فتح قفل الملف</string>

View file

@ -836,6 +836,7 @@
<string name="trashbin_empty_message">You will be able to recover deleted files from here.</string> <string name="trashbin_empty_message">You will be able to recover deleted files from here.</string>
<string name="trashbin_file_not_deleted">File %1$s could not be deleted!</string> <string name="trashbin_file_not_deleted">File %1$s could not be deleted!</string>
<string name="trashbin_file_not_restored">File %1$s could not be restored!</string> <string name="trashbin_file_not_restored">File %1$s could not be restored!</string>
<string name="trashbin_file_remove">Delete permanently</string>
<string name="trashbin_loading_failed">Loading trash bin failed!</string> <string name="trashbin_loading_failed">Loading trash bin failed!</string>
<string name="trashbin_not_emptied">Files could not be deleted permanently!</string> <string name="trashbin_not_emptied">Files could not be deleted permanently!</string>
<string name="unlock_file">Unlock file</string> <string name="unlock_file">Unlock file</string>

View file

@ -807,6 +807,7 @@
<string name="trashbin_empty_message">Ще можете да възстановите изтритите файлове от тук.</string> <string name="trashbin_empty_message">Ще можете да възстановите изтритите файлове от тук.</string>
<string name="trashbin_file_not_deleted">Файлът %1$s не може да бъде изтрит!</string> <string name="trashbin_file_not_deleted">Файлът %1$s не може да бъде изтрит!</string>
<string name="trashbin_file_not_restored">Файлът %1$s не може да бъде възстановен!</string> <string name="trashbin_file_not_restored">Файлът %1$s не може да бъде възстановен!</string>
<string name="trashbin_file_remove">Изтрий завинаги</string>
<string name="trashbin_loading_failed">Зареждането на кошчето е неуспешно!</string> <string name="trashbin_loading_failed">Зареждането на кошчето е неуспешно!</string>
<string name="trashbin_not_emptied">Файловете не могат да бъдат окончателно изтрити!</string> <string name="trashbin_not_emptied">Файловете не могат да бъдат окончателно изтрити!</string>
<string name="unlock_file">Отключване на файл</string> <string name="unlock_file">Отключване на файл</string>

View file

@ -666,6 +666,7 @@
<string name="trashbin_empty_message">Posupl eo deoc\'h adtapout ar restroù lamet adalek al lec\'h mañ</string> <string name="trashbin_empty_message">Posupl eo deoc\'h adtapout ar restroù lamet adalek al lec\'h mañ</string>
<string name="trashbin_file_not_deleted">Ar restr %1$s n\'eo ket evit bezhaãn lamet !</string> <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_file_not_restored">Ar restr %1$s n\'eo ket evit bezha adlakaet !</string>
<string name="trashbin_file_remove">Lamet da viken</string>
<string name="trashbin_not_emptied">N\'eo ket posupl lemel ar restr da virviken !</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="unlock_file">Dibrennan ar restr</string>
<string name="unread_comments">Bez eez eus kemenadennom n\'int ket bet lennet</string> <string name="unread_comments">Bez eez eus kemenadennom n\'int ket bet lennet</string>

View file

@ -796,6 +796,7 @@
<string name="trashbin_empty_message">Des d\'aquí es podran recuperar fitxers suprimits.</string> <string name="trashbin_empty_message">Des d\'aquí es podran recuperar fitxers suprimits.</string>
<string name="trashbin_file_not_deleted">El fitxer %1$s no es pot suprimir!</string> <string name="trashbin_file_not_deleted">El fitxer %1$s no es pot suprimir!</string>
<string name="trashbin_file_not_restored">El fitxer %1$s no es pot restaurar!</string> <string name="trashbin_file_not_restored">El fitxer %1$s no es pot restaurar!</string>
<string name="trashbin_file_remove">Suprimeix permanentment</string>
<string name="trashbin_loading_failed">No s\'ha pogut carregar la paperera!</string> <string name="trashbin_loading_failed">No s\'ha pogut carregar la paperera!</string>
<string name="trashbin_not_emptied">Els fitxers no s\'han pogut suprimir permanentment!</string> <string name="trashbin_not_emptied">Els fitxers no s\'han pogut suprimir permanentment!</string>
<string name="unlock_file">Desbloca el fitxer</string> <string name="unlock_file">Desbloca el fitxer</string>

View file

@ -819,6 +819,7 @@ Enheds legitimationsoplysninger er sat op
<string name="trashbin_empty_message">Du vil kunne gendanne slettede filer herfra.</string> <string name="trashbin_empty_message">Du vil kunne gendanne slettede filer herfra.</string>
<string name="trashbin_file_not_deleted">Fil %1$s kunne ikke slettes!</string> <string name="trashbin_file_not_deleted">Fil %1$s kunne ikke slettes!</string>
<string name="trashbin_file_not_restored">Fil %1$s kunne ikke genskabes!</string> <string name="trashbin_file_not_restored">Fil %1$s kunne ikke genskabes!</string>
<string name="trashbin_file_remove">Slet permanent</string>
<string name="trashbin_loading_failed">Indlæsning af papirkurv mislykkedes!</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="trashbin_not_emptied">Filer kunne ikke permanent slettes!</string>
<string name="unlock_file">Lås op filen</string> <string name="unlock_file">Lås op filen</string>

View file

@ -811,6 +811,7 @@
<string name="trashbin_empty_message">Μπορείτε να ανακτήσετε διαγραμμένα αρχεία από εδώ.</string> <string name="trashbin_empty_message">Μπορείτε να ανακτήσετε διαγραμμένα αρχεία από εδώ.</string>
<string name="trashbin_file_not_deleted">Το αρχείο %1$s δεν μπορεί να διαγραφεί!</string> <string name="trashbin_file_not_deleted">Το αρχείο %1$s δεν μπορεί να διαγραφεί!</string>
<string name="trashbin_file_not_restored">Το αρχείο %1$s δεν μπορεί να ανακτηθεί!</string> <string name="trashbin_file_not_restored">Το αρχείο %1$s δεν μπορεί να ανακτηθεί!</string>
<string name="trashbin_file_remove">Διαγραφή οριστικά</string>
<string name="trashbin_loading_failed">Αποτυχία φόρτωσης κάδου ανακύκλωσης!</string> <string name="trashbin_loading_failed">Αποτυχία φόρτωσης κάδου ανακύκλωσης!</string>
<string name="trashbin_not_emptied">Τα αρχεία δεν θα διαγραφούν μόνιμα!</string> <string name="trashbin_not_emptied">Τα αρχεία δεν θα διαγραφούν μόνιμα!</string>
<string name="unlock_file">Ξεκλείδωμα αρχείου</string> <string name="unlock_file">Ξεκλείδωμα αρχείου</string>